From 09dea46948f6449faeab4761515081f9b41f71be Mon Sep 17 00:00:00 2001 From: AidarKC Date: Mon, 4 May 2026 14:19:40 +0300 Subject: [PATCH] Initial import: shine + solana-shine-client-lib --- shine/.gitignore | 9 + shine/.idea/.gitignore | 10 + shine/.idea/modules.xml | 8 + shine/.idea/shine.iml | 12 + shine/.idea/vcs.xml | 6 + shine/.prettierignore | 7 + shine/AGENTS.md | 9 + shine/Anchor.toml | 39 + shine/Cargo.lock | 3027 +++++++++++++++++ shine/Cargo.toml | 25 + shine/doc/Deploy.txt | 31 + shine/doc/READ_ME.txt | 39 + shine/doc/READ_ME_NEW_DEPLOY.txt | 65 + shine/doc/ReadMe.md | 1 + shine/doc/SHINE_USER_PDA_V1.md | 144 + shine/doc/TODO | 7 + ...getback money after deploy from buffer.txt | 19 + shine/doc/how todo minimal size.txt | 6 + shine/doc/sh/restart.sh | 44 + shine/doc/sh/stop.sh | 23 + shine/doc/что содержит utils.txt | 145 + shine/migrations/deploy.ts | 12 + shine/mu.sh | 29 + shine/package.json | 20 + shine/programs/common/Cargo.toml | 10 + shine/programs/common/src/lib.rs | 1 + shine/programs/common/src/utils.rs | 402 +++ shine/programs/shine_payments/Cargo.toml | 33 + .../shine_payments/dApp/copyToServer.sh | 30 + shine/programs/shine_payments/dApp/init.html | 404 +++ .../shine_payments/src/investments.rs | 326 ++ shine/programs/shine_payments/src/lib.rs | 158 + shine/programs/shine_payments/src/nft.rs | 190 ++ shine/programs/shine_users/Cargo.toml | 30 + shine/programs/shine_users/src/lib.rs | 23 + shine/programs/shine_users/src/settings.rs | 12 + shine/programs/shine_users/src/users.rs | 592 ++++ shine/scripts/devnet/README.md | 76 + shine/scripts/devnet/quick_devnet_e2e.js | 285 ++ .../scripts/devnet/quick_devnet_e2e_multi.js | 205 ++ shine/tests/shine.ts | 16 + shine/tsconfig.json | 10 + shine/validator.log | 3 + shine/yarn.lock | 1144 +++++++ solana-shine-client-lib/.gitignore | 42 + solana-shine-client-lib/.idea/.gitignore | 10 + solana-shine-client-lib/.idea/gradle.xml | 18 + solana-shine-client-lib/.idea/misc.xml | 10 + solana-shine-client-lib/.idea/vcs.xml | 6 + solana-shine-client-lib/build.gradle | 46 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 60756 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + solana-shine-client-lib/gradlew | 234 ++ solana-shine-client-lib/gradlew.bat | 89 + .../libs/tmp/solanaj-1.20.4.jar | Bin 0 -> 222190 bytes solana-shine-client-lib/settings.gradle | 2 + .../solana-shine-lib/build.gradle | 56 + .../solana-shine-lib/libs/solanaj-1.20.4.jar | Bin 0 -> 222190 bytes .../solana-shine-lib/src/main/java/TODO.txt | 9 + .../me/shineup/solana/SolanaSettings.java | 42 + .../me/shineup/solana/SolanaTxWatcher.java | 218 ++ .../java/me/shineup/solana/SolanaWrapper.java | 88 + .../main/java/me/shineup/solana/actions.md | 19 + .../java/me/shineup/solana/config/Const.java | 76 + .../solana/exceptions/ExeptionList.txt | 35 + .../solana/exceptions/SolanaErrorHandler.java | 43 + .../solana/exceptions/SolanaException.java | 13 + .../exceptions/SolanaException_InProgram.java | 41 + .../SolanaException_IncorrectProgramId.java | 12 + ...lanaException_InsufficientFundsForFee.java | 10 + .../exceptions/SolanaException_LibLogic.java | 21 + .../SolanaException_RpcConnection.java | 8 + .../SolanaException_UserNotFound.java | 14 + .../InitializeUserCounter.java | 98 + .../RegisterUser/RegisterUserStepOne.java | 104 + .../RegisterUser/RegisterUserWithOneDev.java | 156 + .../userById/UserByIdParser.java | 103 + .../userById/UserByIdReader.java | 48 + .../userByLogin/UserByLoginParser.java | 73 + .../userByLogin/UserByLoginReader.java | 58 + .../userCounter/UserCounterReader.java | 60 + .../airDrops/SolanaAirdrop.java | 68 + .../balanse/SolanaBalanceChecker.java | 72 + .../keysGenerator/KeyPairBase58.java | 26 + .../SolanaKeyGeneratorManual.java | 101 + .../transfer/SolanaTransfer.java | 73 + .../solana/internal/utils/KeyPair.java | 55 + .../solana/internal/utils/KeyUtils.java | 39 + .../internal/utils/SolanaProgramCaller.java | 378 ++ .../internal/utils/SolanaRpcClient.java | 86 + .../utils/jsonrpc/JsonRpcRequest.java | 19 + .../internal/utils/reader/PdaReader.java | 157 + .../utils/resultChecker/ResultChecker.java | 29 + .../SolanaTransactionStatusChecker.java | 210 ++ .../TransactionStatusChecker.java | 68 + .../TransactionStatusHelper.java | 126 + .../me/shineup/solana/model/TxStatus.java | 22 + .../me/shineup/solana/model/UserById.java | 52 + .../me/shineup/solana/model/UserByLogin.java | 23 + solana-shine-client-lib/src/main/Build.txt | 2 + solana-shine-client-lib/src/main/airDrop.txt | 1 + .../com/shine/solana/test/AddUserExemple.java | 118 + .../java/com/shine/solana/test/AirDrop.java | 32 + .../main/java/com/shine/solana/test/Main.java | 47 + .../com/shine/utils/CreateToken_story.txt | 58 + .../shine/utils/SolanaKeyBase58Converter.java | 110 + .../src/main/java/com/shine/utils/Wallets.txt | 37 + 107 files changed, 11564 insertions(+) create mode 100644 shine/.gitignore create mode 100644 shine/.idea/.gitignore create mode 100644 shine/.idea/modules.xml create mode 100644 shine/.idea/shine.iml create mode 100644 shine/.idea/vcs.xml create mode 100644 shine/.prettierignore create mode 100644 shine/AGENTS.md create mode 100644 shine/Anchor.toml create mode 100644 shine/Cargo.lock create mode 100644 shine/Cargo.toml create mode 100644 shine/doc/Deploy.txt create mode 100644 shine/doc/READ_ME.txt create mode 100644 shine/doc/READ_ME_NEW_DEPLOY.txt create mode 100644 shine/doc/ReadMe.md create mode 100644 shine/doc/SHINE_USER_PDA_V1.md create mode 100644 shine/doc/TODO create mode 100644 shine/doc/how to getback money after deploy from buffer.txt create mode 100644 shine/doc/how todo minimal size.txt create mode 100755 shine/doc/sh/restart.sh create mode 100755 shine/doc/sh/stop.sh create mode 100644 shine/doc/что содержит utils.txt create mode 100644 shine/migrations/deploy.ts create mode 100755 shine/mu.sh create mode 100644 shine/package.json create mode 100644 shine/programs/common/Cargo.toml create mode 100644 shine/programs/common/src/lib.rs create mode 100644 shine/programs/common/src/utils.rs create mode 100644 shine/programs/shine_payments/Cargo.toml create mode 100755 shine/programs/shine_payments/dApp/copyToServer.sh create mode 100644 shine/programs/shine_payments/dApp/init.html create mode 100644 shine/programs/shine_payments/src/investments.rs create mode 100644 shine/programs/shine_payments/src/lib.rs create mode 100644 shine/programs/shine_payments/src/nft.rs create mode 100644 shine/programs/shine_users/Cargo.toml create mode 100644 shine/programs/shine_users/src/lib.rs create mode 100644 shine/programs/shine_users/src/settings.rs create mode 100644 shine/programs/shine_users/src/users.rs create mode 100644 shine/scripts/devnet/README.md create mode 100644 shine/scripts/devnet/quick_devnet_e2e.js create mode 100644 shine/scripts/devnet/quick_devnet_e2e_multi.js create mode 100644 shine/tests/shine.ts create mode 100644 shine/tsconfig.json create mode 100644 shine/validator.log create mode 100644 shine/yarn.lock create mode 100644 solana-shine-client-lib/.gitignore create mode 100644 solana-shine-client-lib/.idea/.gitignore create mode 100644 solana-shine-client-lib/.idea/gradle.xml create mode 100644 solana-shine-client-lib/.idea/misc.xml create mode 100644 solana-shine-client-lib/.idea/vcs.xml create mode 100644 solana-shine-client-lib/build.gradle create mode 100644 solana-shine-client-lib/gradle/wrapper/gradle-wrapper.jar create mode 100644 solana-shine-client-lib/gradle/wrapper/gradle-wrapper.properties create mode 100755 solana-shine-client-lib/gradlew create mode 100644 solana-shine-client-lib/gradlew.bat create mode 100644 solana-shine-client-lib/libs/tmp/solanaj-1.20.4.jar create mode 100644 solana-shine-client-lib/settings.gradle create mode 100644 solana-shine-client-lib/solana-shine-lib/build.gradle create mode 100644 solana-shine-client-lib/solana-shine-lib/libs/solanaj-1.20.4.jar create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/TODO.txt create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/SolanaSettings.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/SolanaTxWatcher.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/SolanaWrapper.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/actions.md create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/config/Const.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/ExeptionList.txt create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaErrorHandler.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InProgram.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_IncorrectProgramId.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InsufficientFundsForFee.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_LibLogic.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_RpcConnection.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_UserNotFound.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/InitializeUserCounter/InitializeUserCounter.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserStepOne.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserWithOneDev.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdParser.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdReader.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginParser.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginReader.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userCounter/UserCounterReader.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/airDrops/SolanaAirdrop.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/balanse/SolanaBalanceChecker.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/KeyPairBase58.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/SolanaKeyGeneratorManual.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/transfer/SolanaTransfer.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyPair.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyUtils.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaProgramCaller.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaRpcClient.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/jsonrpc/JsonRpcRequest.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/reader/PdaReader.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/ResultChecker.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/SolanaTransactionStatusChecker.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusChecker.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusHelper.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/TxStatus.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserById.java create mode 100644 solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserByLogin.java create mode 100644 solana-shine-client-lib/src/main/Build.txt create mode 100644 solana-shine-client-lib/src/main/airDrop.txt create mode 100644 solana-shine-client-lib/src/main/java/com/shine/solana/test/AddUserExemple.java create mode 100644 solana-shine-client-lib/src/main/java/com/shine/solana/test/AirDrop.java create mode 100644 solana-shine-client-lib/src/main/java/com/shine/solana/test/Main.java create mode 100644 solana-shine-client-lib/src/main/java/com/shine/utils/CreateToken_story.txt create mode 100644 solana-shine-client-lib/src/main/java/com/shine/utils/SolanaKeyBase58Converter.java create mode 100644 solana-shine-client-lib/src/main/java/com/shine/utils/Wallets.txt diff --git a/shine/.gitignore b/shine/.gitignore new file mode 100644 index 0000000..4c26dd3 --- /dev/null +++ b/shine/.gitignore @@ -0,0 +1,9 @@ +.anchor +.DS_Store +target +**/*.rs.bk +node_modules +test-ledger +.yarn +program-keypair.json +/old_vers/ diff --git a/shine/.idea/.gitignore b/shine/.idea/.gitignore new file mode 100644 index 0000000..7bc07ec --- /dev/null +++ b/shine/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/shine/.idea/modules.xml b/shine/.idea/modules.xml new file mode 100644 index 0000000..dd6793f --- /dev/null +++ b/shine/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/shine/.idea/shine.iml b/shine/.idea/shine.iml new file mode 100644 index 0000000..477406b --- /dev/null +++ b/shine/.idea/shine.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/shine/.idea/vcs.xml b/shine/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/shine/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/shine/.prettierignore b/shine/.prettierignore new file mode 100644 index 0000000..4142583 --- /dev/null +++ b/shine/.prettierignore @@ -0,0 +1,7 @@ +.anchor +.DS_Store +target +node_modules +dist +build +test-ledger diff --git a/shine/AGENTS.md b/shine/AGENTS.md new file mode 100644 index 0000000..f8b669a --- /dev/null +++ b/shine/AGENTS.md @@ -0,0 +1,9 @@ +# AGENTS.md + +## Documentation Rule + +В проекте есть спецификация пользовательской PDA-записи: + +- `doc/SHINE_USER_PDA_V1.md` + +Если меняется формат записи, сериализация, правила подписи, `prev_hash`, экономика лимитов или связанные ограничения create/update, этот документ нужно обновлять в том же изменении. diff --git a/shine/Anchor.toml b/shine/Anchor.toml new file mode 100644 index 0000000..3494b7c --- /dev/null +++ b/shine/Anchor.toml @@ -0,0 +1,39 @@ +[toolchain] +package_manager = "yarn" + +[features] +resolution = true +skip-lint = false + +[programs.localnet] +shine_users = "5dFcWDNp42Xn9Vv4oDMJzM4obBJ8hvDuAtPX54fT5L3t" #тут надо если что обновлять +shine_payments = "92sgkgx7KHpbhQu81mNGHaKa7skJB7esArVdPM7paDSW" #тут надо если что обновлять + + +[programs.devnet] +shine_users = "5dFcWDNp42Xn9Vv4oDMJzM4obBJ8hvDuAtPX54fT5L3t" #тут надо если что обновлять +shine_payments = "92sgkgx7KHpbhQu81mNGHaKa7skJB7esArVdPM7paDSW" #тут надо если что обновлять + + +[workspace] +members = [ + "programs/shine_users", + "programs/shine_payments", +] + +[registry] +url = "https://api.apr.dev" + +[provider] +cluster = "devnet"#"http://127.0.0.1:8899" # это в какую сеть деплоит по умолчанию +wallet = "~/.config/solana/id.json" # а это с какого кошелько спишутся средства за деплой + +[scripts] +test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" + + + + + + + diff --git a/shine/Cargo.lock b/shine/Cargo.lock new file mode 100644 index 0000000..2ff187b --- /dev/null +++ b/shine/Cargo.lock @@ -0,0 +1,3027 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anchor-attribute-access-control" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f70fd141a4d18adf11253026b32504f885447048c7494faf5fa83b01af9c0cf" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715a261c57c7679581e06f07a74fa2af874ac30f86bd8ea07cca4a7e5388a064" +dependencies = [ + "anchor-syn", + "bs58", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "730d6df8ae120321c5c25e0779e61789e4b70dc8297102248902022f286102e4" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e6e449cc3a37b2880b74dcafb8e5a17b954c0e58e376432d7adc646fb333ef" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7710e4c54adf485affcd9be9adec5ef8846d9c71d7f31e16ba86ff9fc1dd49f" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ecfd49b2aeadeb32f35262230db402abed76ce87e27562b34f61318b2ec83c" +dependencies = [ + "anchor-lang-idl", + "anchor-syn", + "anyhow", + "bs58", + "heck", + "proc-macro2", + "quote", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be89d160793a88495af462a7010b3978e48e30a630c91de47ce2c1d3cb7a6149" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abc6ee78acb7bfe0c2dd2abc677aaa4789c0281a0c0ef01dbf6fe85e0fd9e6e4" +dependencies = [ + "anchor-syn", + "borsh-derive-internal", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134a01c0703f6fd355a0e472c033f6f3e41fac1ef6e370b20c50f4c8d022cea7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6bab117055905e930f762c196e08f861f8dfe7241b92cee46677a3b15561a0a" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-serde", + "anchor-derive-space", + "anchor-lang-idl", + "base64 0.21.7", + "bincode", + "borsh 0.10.4", + "bytemuck", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "anchor-lang-idl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e8599d21995f68e296265aa5ab0c3cef582fd58afec014d01bd0bce18a4418" +dependencies = [ + "anchor-lang-idl-spec", + "anyhow", + "heck", + "regex", + "serde", + "serde_json", + "sha2 0.10.9", +] + +[[package]] +name = "anchor-lang-idl-spec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" +dependencies = [ + "anyhow", + "serde", +] + +[[package]] +name = "anchor-spl" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c08cb5d762c0694f74bd02c9a5b04ea53cefc496e2c27b3234acffca5cd076b" +dependencies = [ + "anchor-lang", + "spl-associated-token-account", + "spl-pod", + "spl-token 7.0.0", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", +] + +[[package]] +name = "anchor-syn" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dc7a6d90cc643df0ed2744862cdf180587d1e5d28936538c18fc8908489ed67" +dependencies = [ + "anyhow", + "bs58", + "cargo_toml", + "heck", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.9", + "syn 1.0.109", + "thiserror 1.0.69", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "borsh-derive 1.5.7", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +dependencies = [ + "once_cell", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" +dependencies = [ + "serde", + "toml 0.8.22", +] + +[[package]] +name = "cc" +version = "1.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "common" +version = "0.1.0" +dependencies = [ + "anchor-lang", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "five8" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75b8549488b4715defcb0d8a8a1c1c76a80661b5fa106b4ca0e7fce59d7d875" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_const" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mpl-token-metadata" +version = "5.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046f0779684ec348e2759661361c8798d79021707b1392cb49f3b5eb911340ff" +dependencies = [ + "borsh 0.10.4", + "num-derive 0.3.3", + "num-traits", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shine_payments" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "anchor-spl", + "common", + "mpl-token-metadata", + "spl-token 4.0.2", +] + +[[package]] +name = "shine_users" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "common", + "ed25519-dalek", + "sha2 0.10.9", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-account-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c17d606a298a205fae325489fbed88ee6dc4463c111672172327e741c8905d" +dependencies = [ + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", +] + +[[package]] +name = "solana-clock" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb482ab70fced82ad3d7d3d87be33d466a3498eb8aa856434ff3c0dfc2e2e31" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall", + "subtle", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "five8", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-instruction" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47298e2ce82876b64f71e9d13a46bc4b9056194e7f9937ad3084385befa50885" +dependencies = [ + "bincode", + "borsh 1.5.7", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4be76cfa9afd84ca2f35ebc09f0da0f0092935ccdac0595d98447f259538c2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307fb2f78060995979e9b4f68f833623565ed4e55d3725f100454ce78a99a1a3" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "586469467e93ceb79048f8d8e3a619bf61d05396ee7de95cb40280301a589d05" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.5.7", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.16", + "lazy_static", + "log", + "memoffset", + "num-bigint", + "num-derive 0.4.2", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror 2.0.12", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473ffe73c68d93e9f2aa726ad2985fe52760052709aaab188100a42c618060ec" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b0268f6c89825fb634a34bd0c3b8fdaeaecfc3728be1d622a8ee6dd577b60d4" +dependencies = [ + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "libsecp256k1", + "solana-define-syscall", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "156bb61a96c605fa124e052d630dba2f6fb57e08c7d15b757e1e958b3ed7b3fe" +dependencies = [ + "hashbrown 0.15.2", +] + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-signature" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" +dependencies = [ + "five8", + "solana-sanitize", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-system-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50c92bc019c590f5e42c61939676e18d14809ed00b2a59695dd5c67ae72c097" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f08746f154458f28b98330c0d55cb431e2de64ee4b8efc98dcbe292e0672b" +dependencies = [ + "bincode", + "num-derive 0.4.2", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools", + "js-sys", + "merlin", + "num-derive 0.4.2", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.12", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "spl-associated-token-account" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76fee7d65013667032d499adc3c895e286197a35a0d3a4643c80e7fd3e9969e3" +dependencies = [ + "borsh 1.5.7", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token 7.0.0", + "spl-token-2022", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-associated-token-account-client" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f8349dbcbe575f354f9a533a21f272f3eb3808a49e2fdc1c34393b88ba76cb" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "spl-discriminator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" +dependencies = [ + "bytemuck", + "solana-program-error", + "solana-sha256-hasher", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.101", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.101", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-elgamal-registry" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0f668975d2b0536e8a8fd60e56a05c467f06021dae037f1d0cfed0de2e231d" +dependencies = [ + "bytemuck", + "solana-program", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction", +] + +[[package]] +name = "spl-memo" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "spl-pod" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "num-derive 0.4.2", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "solana-program-option", + "solana-pubkey", + "solana-zk-sdk", + "thiserror 2.0.12", +] + +[[package]] +name = "spl-program-error" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d39b5186f42b2b50168029d81e58e800b690877ef0b30580d107659250da1d1" +dependencies = [ + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.101", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd99ff1e9ed2ab86e3fd582850d47a739fec1be9f4661cba1782d3a0f26805f3" +dependencies = [ + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9e171cbcb4b1f72f6d78ed1e975cb467f56825c27d09b8dd2608e4e7fc8b3b" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed320a6c934128d4f7e54fe00e16b8aeaecf215799d060ae14f93378da6dc834" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-2022" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b27f7405010ef816587c944536b0eafbcc35206ab6ba0f2ca79f1d28e488f4f" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum", + "solana-program", + "solana-security-txt", + "solana-zk-sdk", + "spl-elgamal-registry", + "spl-memo", + "spl-pod", + "spl-token 7.0.0", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170378693c5516090f6d37ae9bad2b9b6125069be68d9acd4865bbe9fc8499fd" +dependencies = [ + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff2d6a445a147c9d6dd77b8301b1e116c8299601794b558eafa409b342faf96" +dependencies = [ + "bytemuck", + "solana-curve25519", + "solana-program", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.12", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8627184782eec1894de8ea26129c61303f1f0adeed65c20e0b10bc584f09356d" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d595667ed72dbfed8c251708f406d7c2814a3fa6879893b323d56a10bedfc799" +dependencies = [ + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb9c89dbc877abd735f05547dcf9e6e12c00c11d6d74d8817506cab4c99fdbb" +dependencies = [ + "borsh 1.5.7", + "num-derive 0.4.2", + "num-traits", + "solana-borsh", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa7503d52107c33c88e845e1351565050362c2314036ddf19a36cd25137c043" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-type-length-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba70ef09b13af616a4c987797870122863cba03acc4284f226a4473b043923f9" +dependencies = [ + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-discriminator", + "spl-pod", + "thiserror 1.0.69", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] diff --git a/shine/Cargo.toml b/shine/Cargo.toml new file mode 100644 index 0000000..4adb720 --- /dev/null +++ b/shine/Cargo.toml @@ -0,0 +1,25 @@ +[workspace] +members = [ + "programs/common", + "programs/shine_users", + "programs/shine_payments", +] +resolver = "2" + +[profile.release] +overflow-checks = true +lto = "fat" +codegen-units = 1 +[profile.release.build-override] +opt-level = 3 +incremental = false +codegen-units = 1 + + + + + + + + + diff --git a/shine/doc/Deploy.txt b/shine/doc/Deploy.txt new file mode 100644 index 0000000..b1242bd --- /dev/null +++ b/shine/doc/Deploy.txt @@ -0,0 +1,31 @@ +Деплой в devnet (по умолчанию у тебя уже devnet): + обе программы сразу: +anchor deploy + или по одной: +anchor deploy --program-name shine_users +anchor deploy --program-name shine_payments + + Проверка деплоя +anchor keys list +solana program show 5dFcWDNp42Xn9Vv4oDMJzM4obBJ8hvDuAtPX54fT5L3t // +solana program show GcGFR47xF7o7ztXzN4MFThmxzHn4z6VmpmELgNk8smCm // + + Апгрейд в будущем + После изменений кода: +anchor build +anchor upgrade --program-name shine_users +anchor upgrade --program-name shine_payments + + посмотреть адрес кошелька + solana address -k /home/ai/.config/solana/id.jsonanchor build --program-name shine_payments + + + + + + +anchor deploy --program-name shine_payments + +solana program show 92sgkgx7KHpbhQu81mNGHaKa7skJB7esArVdPM7paDSW --url http://127.0.0.1:8899 + +solana address -k /home/ai/work/SOLANA/shine/target/deploy/shine_payments-keypair.json diff --git a/shine/doc/READ_ME.txt b/shine/doc/READ_ME.txt new file mode 100644 index 0000000..89831f0 --- /dev/null +++ b/shine/doc/READ_ME.txt @@ -0,0 +1,39 @@ +# подключаться надо к +JSON RPC URL: http://127.0.0.1:8899 + +# Запустить саму ноду +solana-test-validator +# Удалить процесс ноды что бы запустить заново +kill -9 $(pgrep -f "solana-test-validator") + +или +ps aux | grep solana-test-validator +а потом +kill -9 1052345 +# Убивает и логи и всю базу локальной ноды +rm -rf test-ledger + + +# Удалить все данные с ноды +solana-test-validator --reset + + +# Что бы запустить просмотр логов ноды +solana logs + +# Запустить контракт +anchor deploy + +# Cкомпилировать и задеплоить новую версию +anchor build # Скомпилировать контракт и сгенерировать IDL +anchor deploy # Задеплоить контракт в сеть (указанную в Anchor.toml) +Если ты хочешь сразу убедиться, куда он деплоится — проверь Anchor.toml. +[provider] +cluster = "https://api.testnet.solana.com" # или "localnet" +wallet = "~/.config/solana/id.json" + + + + +# Создать новый проект +anchor init имя_проекта diff --git a/shine/doc/READ_ME_NEW_DEPLOY.txt b/shine/doc/READ_ME_NEW_DEPLOY.txt new file mode 100644 index 0000000..708ca0e --- /dev/null +++ b/shine/doc/READ_ME_NEW_DEPLOY.txt @@ -0,0 +1,65 @@ +https://api.devnet.solana.com + + +проверить настройки +solana config get + +настроить +solana config set --url https://api.devnet.solana.com +или +solana config set --url http://127.0.0.1:8899 + +потом +solana airdrop 2 --keypair /home/ai/.config/solana/id.json +и +solana balance --keypair /home/ai/.config/solana/id.json + + + +anchor deploy \ + --provider.cluster https://api.devnet.solana.com \ + --provider.wallet /home/ai/.config/solana/id.json + + + + + + + + + + + + + + + +Шаг 1. Создай новый ключ для новой программы + +solana-keygen new --outfile target/deploy/user_registry-testnet-keypair.json + +Шаг 2. Укажи новый ID в declare_id!: + +declare_id!("НОВЫЙ_PUBKEY_ОТСЮДА"); // получен из предыдущей команды + +Чтобы узнать pubkey: + +solana address -k target/deploy/user_registry-testnet-keypair.json + +Шаг 3. Обнови Anchor.toml: + +[programs.testnet] +user_registry = "НОВЫЙ_PUBKEY" + +[provider] +cluster = "https://api.testnet.solana.com" +wallet = "~/.config/solana/id.json" + +Шаг 4. Компиляция и деплой: + +anchor build +anchor deploy --provider.cluster testnet + +Шаг 5. Проверка: + +solana program show НОВЫЙ_PUBKEY --url https://api.testnet.solana.com \ No newline at end of file diff --git a/shine/doc/ReadMe.md b/shine/doc/ReadMe.md new file mode 100644 index 0000000..ae846df --- /dev/null +++ b/shine/doc/ReadMe.md @@ -0,0 +1 @@ +Просто разные заметки для себя \ No newline at end of file diff --git a/shine/doc/SHINE_USER_PDA_V1.md b/shine/doc/SHINE_USER_PDA_V1.md new file mode 100644 index 0000000..bda69c1 --- /dev/null +++ b/shine/doc/SHINE_USER_PDA_V1.md @@ -0,0 +1,144 @@ +# SHiNE User PDA v1.0 + +## 1. Назначение + +`SHiNE User PDA v1.0` — бинарный формат пользовательской записи в PDA Solana. + +Хранит: +- логин; +- ключи пользователя; +- номер внутренней сети; +- лимит (баланс); +- серверные данные (опционально); +- список серверов подключения; +- данные восстановления; +- связь с предыдущей версией через `prev_hash`; +- подпись владельца `root_key`. + +Размер PDA фиксированный: + +`768 bytes` + +Полезная длина записи указывается в `record_len`. + +## 2. Общие правила кодирования + +- Числа: `little-endian`. +- Строки: `UTF-8` с префиксом длины `u8`. +- Padding до 768 байт: нули `0x00`. +- Padding не входит в `record_len`. + +## 3. Структура записи + +- `magic` (5): `"SHiNE"` +- `format_major` (1): `1` +- `format_minor` (1): `0` +- `record_len` (2): длина от `magic` до `signature` включительно +- `created_at_ms` (8) +- `updated_at_ms` (8) +- `version` (4) +- `prev_hash` (32) +- `login_len` (1) +- `login` (N) +- `root_key` (32) +- `blockchain_key` (32) +- `device_key` (32) +- `chain_number` (2) +- `balance` (8) +- `is_server` (1) +- если `is_server=1`: + - `server_key` (32) + - `server_address_len` (1) + - `server_address` (N) +- `connection_servers_count` (1) +- повтор `count` раз: + - `server_login_len` (1) + - `server_login` (N) +- `trusted_count` (1) +- `reserved` (5) = `0x00 0x00 0x00 0x00 0x00` +- `signature` (64) +- `padding` до 768 + +## 4. Подпись (v1.0) + +В `v1.0` подписывается не сырой блок полей напрямую, а его SHA-256. + +1. Формируется `unsigned_bytes`: + - все поля от `magic` до `reserved` включительно; + - поле `signature` не включается; + - padding не включается. +2. Считается `msg_hash = SHA-256(unsigned_bytes)`. +3. `signature = Ed25519.sign(root_private_key, msg_hash)`. +4. Проверка: + - `Ed25519.verify(root_key, msg_hash, signature)`. + +## 5. Что входит в `prev_hash` + +Для связи версий: + +- `prev_hash = SHA-256(previous_unsigned_bytes)` + +Где `previous_unsigned_bytes` — предыдущая версия записи от `magic` до `reserved` включительно, без `signature` и без padding. + +Для первой версии: + +- `prev_hash = 32` нулевых байта. + +## 6. Правила create/update в текущей реализации + +### Create + +- PDA: seed `["login=", login]`. +- Создаётся запись версии `0`. +- `updated_at_ms = created_at_ms`. +- Стартовый лимит: + - `START_BONUS_LIMIT + additional_limit`. +- Оплата: + - регистрационная комиссия; + - пополнение `additional_limit` по курсу; + - рента PDA (плательщик транзакции). + +### Update + +- Проверка подписи новой записи по `root_key`. +- Проверка: + - `magic`, `format_major`, `format_minor`; + - корректного `record_len`; + - `prev_hash` на соответствие предыдущей версии; + - `version = old_version + 1`; + - неизменяемых полей: `login`, `created_at_ms`, `root_key`. +- `balance` не уменьшается: + - `new_balance = old_balance + additional_limit`. +- При `additional_limit > 0` берётся комиссия пополнения. + +## 7. Параметры экономики/размера (settings) + +См. `programs/shine_users/src/settings.rs`: + +- `USER_PDA_SPACE = 768` +- `REGISTRATION_FEE_RECEIVER` +- `REGISTRATION_FEE_LAMPORTS` +- `LIMIT_STEP` +- `LAMPORTS_PER_LIMIT_STEP` +- `START_BONUS_LIMIT` + +## 8. Root Key Rotation (пока не включено) + +В `v1.0` `root_key` неизменяем. + +Варианты расширения: + +1. **Dual-signature rotate tx**: + - отдельный флаг операции rotate; + - запись подписывается и старым, и новым root key; + - контракт проверяет обе подписи. + +2. **Two-step commit/confirm**: + - шаг 1: proposal смены root (`old root` подпись); + - шаг 2: confirm (`new root` подпись) в отдельной tx. + +3. **Recovery guardians**: + - отдельная PDA для доверенных лиц; + - пороговая схема (например `m-of-n`) для восстановления root. + +Для v1.0 решение отложено, но изменение root_key в update запрещено. diff --git a/shine/doc/TODO b/shine/doc/TODO new file mode 100644 index 0000000..93bbc21 --- /dev/null +++ b/shine/doc/TODO @@ -0,0 +1,7 @@ +. Сделать новые форматы для пользователей что бы там было больше информации + +. Протестировать работу и может доработать что бы можно было паралельно регистрировать 5 и более юзеров - за счёт передачи при вызове адресов PDA +1 +2 +3 +4 и т.д. + + + +. - пока не надо - Сделать что бы в файле общей информации добавилась запись для будущей миграции пользователей (хотя можно потом и добавить будет :))) \ No newline at end of file diff --git a/shine/doc/how to getback money after deploy from buffer.txt b/shine/doc/how to getback money after deploy from buffer.txt new file mode 100644 index 0000000..3501e79 --- /dev/null +++ b/shine/doc/how to getback money after deploy from buffer.txt @@ -0,0 +1,19 @@ +Как вернуть деньги + + Узнаём адрес buffer account: + +solana program show <адрес_твоей_программы> + +Там будет строчка Buffer: . + +Закрываем буфер: + + solana program close --recipient <адрес_кошелька> + + 💡 --recipient — это куда вернуть SOL (обычно твой же кошелёк из ~/.config/solana/id.json). + +Сколько вернётся + + Если бинарник весит ~400 KB, с одного буфера вернётся ~0.35 SOL. + + У тебя две программы (shine_users, shine_payments), значит можно вернуть ~0.7 SOL. \ No newline at end of file diff --git a/shine/doc/how todo minimal size.txt b/shine/doc/how todo minimal size.txt new file mode 100644 index 0000000..fe6b7f0 --- /dev/null +++ b/shine/doc/how todo minimal size.txt @@ -0,0 +1,6 @@ +✅ Чтобы максимально уменьшить .so надо будет включить флаг оптимизации в Cargo.toml: + +[profile.release] +opt-level = "z" # Максимальная компрессия +lto = true # Link Time Optimization +codegen-units = 1 # Уменьшает размер бинаря diff --git a/shine/doc/sh/restart.sh b/shine/doc/sh/restart.sh new file mode 100755 index 0000000..e13ccd0 --- /dev/null +++ b/shine/doc/sh/restart.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +set -e # Завершаем при ошибке +set -o pipefail + + + + + +PROGRAM_KEYPAIR="target/deploy/shine-keypair.json" # замени на свой путь +WALLET=$(solana address) + +echo "🧹 Удаление старого ledger..." +rm -rf test-ledger + +echo "🚀 Запуск solana-test-validator в фоне..." +solana-test-validator --ledger test-ledger --reset > validator.log 2>&1 & +VALIDATOR_PID=$! + +# Убедимся, что validator запущен +echo "⏳ Ожидание запуска валидатора..." +until solana cluster-version &>/dev/null; do + sleep 1 +done +sleep 2 # На всякий случай немного подождём + +echo "💸 Airdrop 10 SOL на $WALLET..." +solana airdrop 10 HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA + +solana airdrop 5 $WALLET + +echo "🔨 Сборка контракта..." +anchor build + +echo "📦 Деплой контракта..." +anchor deploy + +echo "✅ Готово!" + +# Не убиваем валидатор, чтобы он оставался запущенным +echo "ℹ️ Валидатор всё ещё работает (PID $VALIDATOR_PID)" + +echo "ℹ️ Запускаем логи" +solana logs diff --git a/shine/doc/sh/stop.sh b/shine/doc/sh/stop.sh new file mode 100755 index 0000000..c54d0a4 --- /dev/null +++ b/shine/doc/sh/stop.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e # Завершаем при ошибке +set -o pipefail + + +kill -9 $(pgrep -f "solana-test-validator") + +# 🔍 Ищем запущенный solana-test-validator +EXISTING_PID=$(pgrep -f "solana-test-validator") + +if [ -n "$EXISTING_PID" ]; then + echo "🛑 Найден работающий solana-test-validator (PID $EXISTING_PID), останавливаем..." + bash kill -9 $(pgrep -f "solana-test-validator") + echo "✅ Пытаюсь остановить старый валидатор..." + + # ждём завершения + while kill -0 "$EXISTING_PID" 2>/dev/null; do + sleep 0.5 + done + echo "✅ Старый валидатор остановлен." +fi + diff --git a/shine/doc/что содержит utils.txt b/shine/doc/что содержит utils.txt new file mode 100644 index 0000000..2ee02f1 --- /dev/null +++ b/shine/doc/что содержит utils.txt @@ -0,0 +1,145 @@ +Функции для работы с PDA: + + +🧩 create_pda(...) + + Создаёт новый PDA, если он ещё не существует. + + Проверяет, чтобы не было коллизии. + + Без записи данных. + +🧩 write_to_pda(...) + + Просто записывает байты в существующий PDA. + + Без создания. + +🧩 create_and_write_pda(...) + + Комбинированная функция. + + Сначала проверяет, есть ли PDA — если нет, создаёт. + + Затем записывает данные. + + Очень удобна для инициализации одного PDA в один вызов. + +🧩 safe_read_pda(...) + + Возвращает Vec с содержимым PDA. + + Никогда не паникует: если PDA не существует или пустой — просто отдаёт Vec::new(). + + Защита от двойного borrow'а (через try_borrow_data()). + + Отличный инструмент для безопасного считывания данных. + +💡 Да, с этим ты можешь: +Возможность Функция +📦 Создать PDA create_pda +💾 Записать в PDA write_to_pda +⚡ Создать и записать create_and_write_pda +📖 Безопасно прочитать safe_read_pda + + +🔧 create_pda(...) + +🔹 Назначение: +Создаёт новый PDA-аккаунт, если он ещё не существует. + +📥 Аргументы: + + pda_account: &AccountInfo — аккаунт, который хотим создать + + signer: &AccountInfo — аккаунт плательщика (обычно пользователь) + + system_program: &AccountInfo — системная программа + + program_id: &Pubkey — адрес текущей программы + + seeds: &[&[u8]] — массив сидов, по которым создавался PDA + + space: u64 — сколько байт выделить под данные + +📤 Возвращает: + + Result<()> — Ok если успешно, Err если PDA уже существует или при ошибке создания + +🧠 Особенности: + + Проверяет, что PDA ещё не создан (через pda_account.owner == Pubkey::default()) + + Выбрасывает ErrCode::PdaAlreadyExists, если уже существует + +🔧 write_to_pda(...) + +🔹 Назначение: +Записывает бинарные данные в существующий PDA. + +📥 Аргументы: + + pda_account: &AccountInfo — аккаунт, в который пишем + + data: &[u8] — массив байт, которые нужно записать + +📤 Возвращает: + + Result<()> — Ok при успехе, Err если не удалось получить доступ к данным + +🧠 Особенности: + + ⚠️ Только пишет, не создаёт PDA + + Записывает в начало data-секции аккаунта + +🔧 create_and_write_pda(...) + +🔹 Назначение: +Если PDA ещё не существует — создаёт, затем сразу записывает данные. + +📥 Аргументы: + + pda_account: &AccountInfo — аккаунт для создания/записи + + signer: &AccountInfo — кто оплачивает создание + + system_program: &AccountInfo — системная программа + + program_id: &Pubkey — адрес текущей программы + + seeds: &[&[u8]] — сиды PDA + + data: Vec — данные для записи + + space: u64 — сколько байт выделить (при создании) + +📤 Возвращает: + + Result<()> — Ok при успехе, Err при ошибке создания или записи + +🧠 Особенности: + + Безопасно создаёт и пишет за один вызов + + Не выбрасывает ошибку, если PDA уже существует — просто пишет + +🔧 safe_read_pda(...) + +🔹 Назначение: +Безопасно считывает байты из PDA. Никогда не паникует. + +📥 Аргументы: + + pda_account: &AccountInfo — аккаунт для чтения + +📤 Возвращает: + + Vec — массив байт с содержимым PDA + → Если аккаунт не инициализирован или пустой, возвращает Vec::new() + +🧠 Особенности: + + Не выбрасывает ошибки — только логирует + + Полностью безопасно: подходит для чтения read-only PDA в любой ситуации \ No newline at end of file diff --git a/shine/migrations/deploy.ts b/shine/migrations/deploy.ts new file mode 100644 index 0000000..439431e --- /dev/null +++ b/shine/migrations/deploy.ts @@ -0,0 +1,12 @@ +// Migrations are an early feature. Currently, they're nothing more than this +// single deploy script that's invoked from the CLI, injecting a provider +// configured from the workspace's Anchor.toml. + +import * as anchor from "@coral-xyz/anchor"; + +module.exports = async function (provider: anchor.AnchorProvider) { + // Configure client to use the provider. + anchor.setProvider(provider); + + // Add your deploy script here. +}; diff --git a/shine/mu.sh b/shine/mu.sh new file mode 100755 index 0000000..90132e9 --- /dev/null +++ b/shine/mu.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Кол-во адресов для генерации +NUM_KEYS=5 + +# RPC endpoint (можешь поменять) +#RPC_URL="https://api.testnet.solana.com" +RPC_URL="http://127.0.0.1:8899" + +echo "👉 Используем RPC: $RPC_URL" + +for i in $(seq 1 $NUM_KEYS); do + KEYPAIR="temp-key-$i.json" + echo "🔐 Генерирую ключ №$i: $KEYPAIR" + solana-keygen new --outfile "$KEYPAIR" --no-bip39-passphrase --silent + + PUBKEY=$(solana-keygen pubkey "$KEYPAIR") + echo "🪙 Публичный ключ: $PUBKEY" + + echo "💸 Запрашиваю airdrop на $PUBKEY..." + solana airdrop 1 "$PUBKEY" --url "$RPC_URL" + + echo "🔍 Проверяю баланс:" + solana balance "$PUBKEY" --url "$RPC_URL" + echo "-----------------------------" +done + +echo "✅ Готово. Удаляю временные ключи..." +rm temp-key-*.json diff --git a/shine/package.json b/shine/package.json new file mode 100644 index 0000000..7d765e5 --- /dev/null +++ b/shine/package.json @@ -0,0 +1,20 @@ +{ + "license": "ISC", + "scripts": { + "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", + "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" + }, + "dependencies": { + "@coral-xyz/anchor": "^0.31.1" + }, + "devDependencies": { + "chai": "^4.3.4", + "mocha": "^9.0.3", + "ts-mocha": "^10.0.0", + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "typescript": "^5.7.3", + "prettier": "^2.6.2" + } +} diff --git a/shine/programs/common/Cargo.toml b/shine/programs/common/Cargo.toml new file mode 100644 index 0000000..2b3ee68 --- /dev/null +++ b/shine/programs/common/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "common" +version = "0.1.0" +edition = "2021" + +[dependencies] +anchor-lang = "0.31.1" + + +[features] diff --git a/shine/programs/common/src/lib.rs b/shine/programs/common/src/lib.rs new file mode 100644 index 0000000..b5614dd --- /dev/null +++ b/shine/programs/common/src/lib.rs @@ -0,0 +1 @@ +pub mod utils; diff --git a/shine/programs/common/src/utils.rs b/shine/programs/common/src/utils.rs new file mode 100644 index 0000000..77eb884 --- /dev/null +++ b/shine/programs/common/src/utils.rs @@ -0,0 +1,402 @@ +use anchor_lang::prelude::*; +use anchor_lang::solana_program::{ + program::invoke_signed, + system_instruction, + system_program +}; + + + + + + +/// сдесь коды всех ошибок + +#[error_code] +pub enum ErrCode { + /// Система уже инициализирована и не может быть инициализирована повторно! + #[msg("Система уже инициализирована и не может быть инициализирована повторно!")] + SystemAlreadyInitialized = 1000, + + #[msg("PDA не содержит данных или не инициализирован")] + EmptyPdaData = 1002, + + #[msg("Пользователь уже зарегистрирован")] + UserAlreadyExists = 1003, + + #[msg("Некорректный логин")] + InvalidLogin = 1004, + + #[msg("Не совпадает PDA адрес")] + InvalidPdaAddress = 1006, + + #[msg("Формат данных не поддерживается")] + UnsupportedFormat = 1011, + + #[msg("Ошибка при десериализации")] + DeserializationError = 1012, + + /// PDA уже существует, создание невозможно + #[msg("PDA-аккаунт уже существует и не может быть создан повторно.")] + PdaAlreadyExists = 1009, + + + #[msg("Подписавший не совпадает с ожидаемым пользователем (это потому что пока временно можно регистрировать пользователя с другово аккаунта")] + InvalidSigner = 1005, + + /// Не получилось создат ьпользователя, система уже перегружена, попробуйте поззже!" + #[msg("Не получилось создать пользователя, система уже перегружена, попробуйте поззже!")] + NoSuitableIdPda = 1010, + + #[msg("Невалидная цифровая подпись записи")] + InvalidSignature = 1013, + + #[msg("Невалидный формат записи")] + InvalidRecordFormat = 1014, + + #[msg("Невалидная длина записи")] + InvalidRecordLength = 1015, + + #[msg("Невалидные данные записи")] + InvalidRecordData = 1016, + + #[msg("Невалидный хэш предыдущей версии")] + InvalidPrevHash = 1017, + + #[msg("Попытка изменить неизменяемое поле")] + ImmutableFieldChanged = 1018, + + #[msg("Попытка уменьшить лимит/баланс")] + BalanceDecrease = 1019, + + #[msg("Невалидная версия записи")] + InvalidVersion = 1020, + + #[msg("Размер записи превышает допустимый")] + RecordTooLarge = 1021, + + #[msg("Переполнение при вычислении")] + MathOverflow = 1022, + + #[msg("Неверный адрес получателя комиссии")] + InvalidFeeReceiver = 1023, + + #[msg("Пополнение лимита должно быть кратно шагу")] + InvalidLimitIncrement = 1024, + + #[msg("Невалидная magic-сигнатура записи")] + InvalidRecordMagic = 1025, + + +} + + + + + + + + + + + + + + + + + + + + +///---------------------------------------------------------------------------------------------------------- +/// Базовые функции для работы с PDA +///---------------------------------------------------------------------------------------------------------- + +/// Создаёт PDA аккаунт (если его ещё нет), и записывает в него массив байт. +/// +/// Аргументы: +/// - `pda_account`: аккаунт, куда записываем +/// - `signer`: кто платит за создание (обычно пользователь) +/// - `program_id`: адрес текущей программы +/// - `seeds`: слайс сидов, по которым создавался PDA +/// - `data`: байты для записи +/// - `space`: желаемый размер аккаунта +pub fn create_and_write_pda<'info>( + pda_account: &AccountInfo<'info>, + signer: &AccountInfo<'info>, + system_program: &AccountInfo<'info>, + program_id: &Pubkey, + seeds: &[&[u8]], + data: Vec, + space: u64, +) -> Result<()> { + // ─────────────────────────────────────────────── + // 1. Проверяем, создан ли аккаунт (если нет — owner = default) + if pda_account.owner == &Pubkey::default() { + msg!("Создаём PDA с размером {} байт", space); + + let space = space; //+ 128; // Добавляется запас под метаданные + // Вычисляем необходимую арендную плату + let lamports = Rent::get()?.minimum_balance(space as usize); + + // Формируем инструкцию + let create_instr = system_instruction::create_account( + signer.key, + pda_account.key, + lamports, + space, + program_id, + ); + + // Выполняем инструкцию с подписью от PDA + invoke_signed( + &create_instr, + &[ + signer.clone(), + pda_account.clone(), + system_program.clone(), + ], + &[&seeds], + )?; + } + + // ─────────────────────────────────────────────── + // 2. Пишем данные в аккаунт + let mut account_data = pda_account.try_borrow_mut_data()?; + + let copy_len = std::cmp::min(account_data.len(), data.len()); + account_data[..copy_len].copy_from_slice(&data[..copy_len]); + + // Если хочешь дополнить оставшееся нулями — раскомментируй: + // for i in copy_len..account_data.len() { + // account_data[i] = 0; + // } + + msg!("Успешно записано {} байт в PDA", copy_len); + Ok(()) +} + + + + +/// Создаёт PDA аккаунт (если его ещё нет). +/// +/// ⚠️ Если аккаунт уже существует, выбрасывается ошибка. +/// Используется внутри инструкций смарт-контракта. +/// +/// Аргументы: +/// - `pda_account`: аккаунт, который хотим создать (PDA) +/// - `signer`: кто оплачивает создание аккаунта (обычно пользователь) +/// - `system_program`: системная программа (`111...111`) +/// - `program_id`: адрес текущей программы (используется для подписи PDA) +/// - `seeds`: массив сидов, по которым вычислялся PDA +/// - `space`: желаемый размер аккаунта в байтах (только данных, без метаданных) +pub fn create_pda<'info>( + pda_account: &AccountInfo<'info>, + signer: &AccountInfo<'info>, + system_program: &AccountInfo<'info>, + program_id: &Pubkey, + seeds: &[&[u8]], + space: u64, +) -> Result<()> { + // ─────────────────────────────────────────────── + // 1. Проверяем, существует ли аккаунт + if pda_account.owner != &Pubkey::default() { + // Если владелец не равен Pubkey::default, значит аккаунт уже создан + // Возвращаем ошибку с пояснением + return Err(error!(ErrCode::PdaAlreadyExists)); + } + + // ─────────────────────────────────────────────── + // 2. Логируем, что будем создавать PDA + msg!("Создаём PDA-аккаунт на {} байт", space); + + // Добавляем запас под метаданные Solana (примерно 128 байт) + let full_space = space; + + // Получаем минимальный баланс для аренды (чтобы аккаунт не удалили) + let lamports = Rent::get()?.minimum_balance(full_space as usize); + + // ─────────────────────────────────────────────── + // 3. Создаём инструкцию system_program для создания аккаунта + let create_instr = system_instruction::create_account( + signer.key, // от имени кого + pda_account.key, // для какого PDA + lamports, // сколько лампортов перевести + full_space, // сколько байт выделить + program_id, // кто будет владельцем PDA + ); + + // ─────────────────────────────────────────────── + // 4. Выполняем инструкцию с подписью PDA (через сиды) + invoke_signed( + &create_instr, + &[ + signer.clone(), + pda_account.clone(), + system_program.clone(), + ], + &[&seeds], // PDA сиды → для подписи + )?; + + Ok(()) +} + +/// Записывает массив байт в PDA аккаунт (в начало data-секции). +/// +/// ⚠️ Убедись, что PDA был передан как `#[account(mut)]` +/// ⚠️ Эта функция ничего не создаёт, только пишет. +/// +/// Аргументы: +/// - `pda_account`: аккаунт, в который пишем (должен быть mut) +/// - `data`: бинарный массив, который нужно записать +pub fn write_to_pda<'info>( + pda_account: &AccountInfo<'info>, + data: &[u8], +) -> Result<()> { + // ─────────────────────────────────────────────── + // 1. Получаем доступ к данным PDA (на запись) + let mut account_data = pda_account.try_borrow_mut_data()?; + + // ─────────────────────────────────────────────── + // 2. Вычисляем сколько байт реально можно записать + // (на случай, если data длиннее, чем выделено место) + let copy_len = std::cmp::min(account_data.len(), data.len()); + + // ─────────────────────────────────────────────── + // 3. Копируем данные в аккаунт (с самого начала) + account_data[..copy_len].copy_from_slice(&data[..copy_len]); + + // Логируем, сколько байт записано + msg!("Успешно записано {} байт в PDA", copy_len); + + Ok(()) +} + + + + + + + + + + +/// ------------------------------------------------------------------------ +/// safe_read_pda ‒ «безопасное чтение PDA» +/// ------------------------------------------------------------------------ +/// +/// * Принимает: ссылку на `AccountInfo<'info>` PDA-аккаунта. +/// * Возвращает: `Vec` с данными аккаунта. +/// Если аккаунта нет или его данные пусты — возвращается `Vec::new()` +/// длиной 0 байт. +/// +/// Как работает ─────────────────────────────────────────────────────────── +/// 1. Проверяем, что аккаунт **инициализирован**: у не-инициализированного +/// owner = Pubkey::default(). Если owner нулевой — сразу отдаём пустой вектор. +/// 2. Если длина буфера == 0 (Anchor helper `data_is_empty()`), тоже отдаём пустой. +/// 3. Пытаемся безопасно (`try_borrow_data`) получить ссылку на данные. +/// - Успех → копируем их в Vec и возвращаем. +/// - Ошибка (например, конфликт borrow) → логируем и возвращаем пустой Vec. +/// +/// пример использования +/// let raw_bytes = safe_read_pda(&ctx.accounts.readonly_pda); +/// require!(!raw_bytes.is_empty(), ErrCode::EmptyPdaData); +/// msg!("Размер считанных данных: {}", raw_bytes.len()); +/// ------------------------------------------------------------------------ +pub fn safe_read_pda<'info>(pda_account: &AccountInfo<'info>) -> Vec { + // ───────────────────────────────────────────────────────────────────── + // 1) Аккаунт Н*Е* СУЩЕСТВУЕТ или не инициализирован: + // owner == Pubkey::default() (в Solana нулевой owner у пустого счёта) + // ───────────────────────────────────────────────────────────────────── + if pda_account.owner == &Pubkey::default() { + msg!("safe_read_pda: аккаунт не инициализирован ‒ возвращаем пустой массив"); + return Vec::new(); // [] + } + + // ───────────────────────────────────────────────────────────────────── + // 2) У аккаунта нет данных (длина 0) — тоже считаем «пустым» + // ───────────────────────────────────────────────────────────────────── + if pda_account.data_is_empty() { + msg!("safe_read_pda: у аккаунта data_len == 0 ‒ возвращаем пустой массив"); + return Vec::new(); + } + + // ───────────────────────────────────────────────────────────────────── + // 3) Пытаемся безопасно забрать буфер данных; ошибки перехватываем + // ───────────────────────────────────────────────────────────────────── + match pda_account.try_borrow_data() { + Ok(data_ref) => { + // to_vec() копирует bytes → Vec, чтобы дальше работать без borrow-лифа + data_ref.to_vec() + } + Err(e) => { + // Ошибка при borrow (например, уже есть активное мутабельное заимствование) + msg!("safe_read_pda: ошибка borrow_data ({:?}) ‒ возвращаем пустой массив", e); + Vec::new() + } + } +} + + + + + + +/// ------------------------------------------------------------------------ +/// delete_pda_with_assign — закрыть PDA, вернуть ренту и освободить адрес +/// ------------------------------------------------------------------------ +/// +/// Параметры: +/// - `pda_account` : PDA-аккаунт (mut), который закрываем (owned вашей программой) +/// - `recipient` : счёт, на который возвращаем лампорты (обычно пользователь) +/// - `system_program`: системная программа (111...111) +/// - `program_id` : Pubkey вашей программы (проверка владельца) +/// - `seeds` : сиды PDA (в том же порядке, как при создании), чтобы PDA «подписал» assign +/// +/// Делает: +/// 1) Проверяет, что PDA принадлежит вашей программе. +/// 2) Обнуляет данные и сжимает их до 0 байт (realloc(0)). +/// 3) Переводит все лампорты PDA на `recipient`. +/// 4) Делает `assign` владельца на System Program (через `invoke_signed`). +/// +/// Результат: +/// — В конце транзакции аккаунт с lamports=0 и data_len=0 будет удалён рантаймом, +/// владелец = System Program (чисто/ожидаемо). +/// — В следующей транзакции можно снова создать PDA с тем же сидом. +/// ------------------------------------------------------------------------ + +pub fn delete_pda_return_rent<'info>( + pda_account: &AccountInfo<'info>, + recipient: &AccountInfo<'info>, + program_id: &Pubkey, +) -> Result<()> { + // 0) проверки + require!(pda_account.owner != &Pubkey::default(), ErrCode::EmptyPdaData); + require!(pda_account.owner == program_id, ErrCode::InvalidPdaAddress); + + // 1) Переложить все лампорты с PDA на получателя (мы владелец, это разрешено) + let amount = **pda_account.lamports.borrow(); + if amount > 0 { + **recipient.lamports.borrow_mut() = recipient + .lamports() + .checked_add(amount) + .ok_or(ProgramError::InsufficientFunds)?; + **pda_account.lamports.borrow_mut() = 0; + } + + // 2) Нулим данные (если были) + if !pda_account.data_is_empty() { + let mut data = pda_account.try_borrow_mut_data()?; + for b in data.iter_mut() { *b = 0; } + } + + // 3) Сжать до 0 байт + pda_account.realloc(0, false)?; + + // Никаких assign/transfer больше не делаем — это надёжнее. + msg!("PDA закрыт: рента отправлена на {}", recipient.key); + Ok(()) +} + diff --git a/shine/programs/shine_payments/Cargo.toml b/shine/programs/shine_payments/Cargo.toml new file mode 100644 index 0000000..add95e4 --- /dev/null +++ b/shine/programs/shine_payments/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "shine_payments" +version = "0.1.0" +description = "Payments and investments smart contract" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "shine_payments" +test = false +doctest = false +bench = false + +[dependencies] +anchor-lang = "0.31.1" +common = { path = "../common" } + +# ==== добавлено для NFT-функционала ==== +anchor-spl = { version = "0.31.1", features = ["associated_token", "token"] } +mpl-token-metadata = "5.1.1" +spl-token = { version = "4.0.0", features = ["no-entrypoint"] } +# ====================================== + +[features] +default = [] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +anchor-debug = [] +custom-heap = [] +custom-panic = [] +cpi = [] +idl-build = ["anchor-lang/idl-build"] diff --git a/shine/programs/shine_payments/dApp/copyToServer.sh b/shine/programs/shine_payments/dApp/copyToServer.sh new file mode 100755 index 0000000..55f4dfd --- /dev/null +++ b/shine/programs/shine_payments/dApp/copyToServer.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Скрипт для копирования dApp на тестовый сервер + +# Настройки +LOCAL_FILE="init.html" +REMOTE_USER="aidar" +REMOTE_HOST="shineup.me" +REMOTE_PATH="/home/aidar/Docker_server/site/dApp" + +# Проверка, что файл существует +if [ ! -f "$LOCAL_FILE" ]; then + echo "Ошибка: файл $LOCAL_FILE не найден." + exit 1 +fi + +# Копирование файла +scp "$LOCAL_FILE" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}" + +# Проверка результата +if [ $? -eq 0 ]; then + echo "Файл успешно загружен на сервер." +else + echo "Ошибка при загрузке файла на сервер." + exit 1 +fi + +#echo +#echo "Нажмите Enter, чтобы закрыть..." +#read diff --git a/shine/programs/shine_payments/dApp/init.html b/shine/programs/shine_payments/dApp/init.html new file mode 100644 index 0000000..3e2b8ac --- /dev/null +++ b/shine/programs/shine_payments/dApp/init.html @@ -0,0 +1,404 @@ + + + + + + Shine Payments — Phantom demo (devnet, deep logs) + + + + + + + +

Shine Payments — Phantom wallet (devnet)

+ +
+ + + + + +
+ +
+ В Phantom выбери сеть Devnet. Логи ниже и в консоли (F12 → Console). +
+ +

+
+
+
+
+
+
diff --git a/shine/programs/shine_payments/src/investments.rs b/shine/programs/shine_payments/src/investments.rs
new file mode 100644
index 0000000..b9d71fa
--- /dev/null
+++ b/shine/programs/shine_payments/src/investments.rs
@@ -0,0 +1,326 @@
+use anchor_lang::prelude::*;
+
+use anchor_lang::solana_program::{program::invoke_signed, system_instruction};
+use common::utils::*; // тянем общие PDA-хелперы из programs/common
+
+// === добавлено: используем наш NFT-модуль ===
+use crate::nft::{CreateNftParams, create_nft_with_freeze};
+// ============================================
+
+/// Утилита чтения структуры из PDA: читает байты и десериализует.
+/// Возвращает ошибку, если данных нет/пустые/неверный формат.
+fn read_state_from_pda(pda: &AccountInfo) -> Result {
+    let raw = safe_read_pda(pda);                         // ← берём Vec (или пустой)
+    require!(!raw.is_empty(), ErrCode::EmptyPdaData);     // ← пусто — ошибка
+    let st = deserialize_invest_state(&raw)?;             // ← десериализуем по формату
+    require!(st.format == INVEST_STATE_FORMAT_V1, ErrCode::UnsupportedFormat); // ← проверяем версию
+    Ok(st)
+}
+
+/// Утилита записи структуры в PDA: сериализует и пишет.
+/// Важно: сам аккаунт уже должен существовать и быть #[account(mut)].
+fn write_state_to_pda(pda: &AccountInfo, s: &InvestState) -> Result<()> {
+    let raw = serialize_invest_state_v1(s); // ← 24 байта
+    write_to_pda(pda, &raw)                 // ← записываем в начало data
+}
+
+/// ==============================================
+/// Контексты инструкций (минимально необходимые)
+/// ==============================================
+
+/// init: создаём PDA и кладём в него PayStateV1 {format=1, coef=10, ...0}
+#[derive(Accounts)]
+pub struct Init<'info> {
+    /// Плательщик аренды за PDA; подписант транзакции.
+    #[account(mut)]
+    pub payer: Signer<'info>,
+
+    /// Наш PDA (с произвольным типом, чтобы работать через AccountInfo).
+    /// Проверку адреса делаем в handler (по seed + bump), чтобы избежать подмены.
+    /// CHECK: проверяется вручную по адресу
+    #[account(mut)]
+    pub state_pda: UncheckedAccount<'info>,
+
+    /// Системная программа.
+    pub system_program: Program<'info, System>,
+}
+
+/// Общие аккаунты для invest/add_bonus/claim:
+/// Везде просто читаем/пишем одно и то же состояние из того же PDA.
+#[derive(Accounts)]
+pub struct UseState<'info> {
+    /// Любой платящий/подписант (в реальном коде — свои проверки).
+    pub signer: Signer<'info>,
+
+    /// Тот же PDA с состоянием (должен уже существовать).
+    /// CHECK: проверяется вручную по адресу
+    #[account(mut)]
+    pub state_pda: UncheckedAccount<'info>,
+
+    /// Системная программа (на всякий случай; может не понадобиться).
+    pub system_program: Program<'info, System>,
+}
+
+/// ==============================================
+/// Программа
+/// ==============================================
+
+use super::*;
+use anchor_lang::prelude::*;
+
+
+/// ------------------------------------------
+/// init: создаёт PDA и записывает в него дефолтное состояние.
+/// format = 1, coef = 10, остальные поля = 0.
+/// ------------------------------------------
+pub fn init(ctx: Context) -> Result<()> {
+    let program_id = ctx.program_id; // ← адрес этой программы
+
+    // 1. Проверка что вызывает именно разрешённый ключ
+    /* todo   пока все могут вызыватьно                                         !! но в итоге будет добавленна проверка что бы только дао могло вызвать эту функцию один раз
+    require_keys_eq!(
+        ctx.accounts.payer.key(),
+        ALLOWED_INIT_CALLER,
+        ErrCode::InvalidSigner
+    );
+*/
+
+    // 2. Проверка что PDA ещё не создан
+    if ctx.accounts.state_pda.data_len() > 0 && ctx.accounts.state_pda.owner != &System::id() {
+        return Err(error!(ErrCode::PdaAlreadyExists));
+    }
+    
+    // 2. Ещё раз Проверка что PDA ещё не создан  
+    if ctx.accounts.state_pda.owner != &System::id()
+        || ctx.accounts.state_pda.lamports() > 0
+    {
+        // Если аккаунт уже создан и не пустой
+        return Err(error!(ErrCode::PdaAlreadyExists));
+    }
+    
+    let pda_key_expected = Pubkey::find_program_address(&[crate::PDA_SEED_PREFIX], program_id).0; // ← вычисляем PDA
+    require_keys_eq!(
+        pda_key_expected,
+        ctx.accounts.state_pda.key(),
+        ErrCode::InvalidPdaAddress
+    ); // ← убеждаемся, что нам подали именно правильный PDA
+
+    // Конструируем дефолтную структуру состояния.
+    let state = InvestState {
+        format: INVEST_STATE_FORMAT_V1,  // ← 1
+        coef: crate::DEFAULT_COEF,       // ← 10
+        q1_tokens: 0,                    // ← нули
+        sum1_bonus: 0,
+        q1_paid_tokens: 0,
+        sum1_paid_bonus: 0,
+    };
+
+    // Сериализуем в 24 байта.
+    let data = serialize_invest_state_v1(&state);
+
+    // Для подписи PDA нужен bump; здесь получим (ключ, bump).
+    let (_pda_key, bump) = Pubkey::find_program_address(&[crate::PDA_SEED_PREFIX], program_id);
+
+    // Сиды для invoke_signed: [seed, bump]
+    let seeds: [&[u8]; 2] = [crate::PDA_SEED_PREFIX, &[bump]];
+
+    // Создаём и сразу записываем, арендный минимум оплачивает payer.
+    create_and_write_pda(
+        &ctx.accounts.state_pda.to_account_info(),   // куда пишем
+        &ctx.accounts.payer.to_account_info(),       // кто платит
+        &ctx.accounts.system_program.to_account_info(),
+        program_id,
+        &seeds,
+        data,
+        crate::PAY_STATE_SPACE,                      // резерв с запасом
+    )?;
+
+    Ok(())
+}
+
+/// ------------------------------------------
+/// invest: «внос инвестиций».
+/// По заданию: в начале читаем состояние, в конце сохраняем.
+/// (Здесь логика модификации не задана — оставляем как заглушку.)
+/// ------------------------------------------
+pub fn invest(ctx: Context, _amount: u64) -> Result<()> {
+    // 1) читаем
+    let mut st = read_state_from_pda(&ctx.accounts.state_pda.to_account_info())?; // ← PayStateV1
+
+    // --- тут можно модифицировать st по твоей бизнес-логике ---
+    // Например, ничего не меняем сейчас (заглушка).
+    let _ = &mut st; // чтоб компилятор не ругался, если пока не используем
+
+    // 2) сохраняем
+    write_state_to_pda(&ctx.accounts.state_pda.to_account_info(), &st)?;
+    Ok(())
+}
+
+/// ------------------------------------------
+/// add_bonus: «начисление бонусов» (обычно вызывать от DAO).
+/// По заданию: читаем в начале, создаём/добавляем NFT в очередь, сохраняем в конце.
+/// Для операций с NFT используем расширенный контекст AddBonusCtx (см. lib.rs).
+/// ------------------------------------------
+pub fn add_bonus(ctx: Context, investor: Pubkey, amount: u64) -> Result<()> {
+    // 1) читаем состояние
+    let mut st = read_state_from_pda(&ctx.accounts.state_pda.to_account_info())?;
+
+    // 2) создаём/добавляем NFT через модуль nft (создание metadata, mint 1, freeze, master edition, verify)
+    let next_index = st.q1_tokens as u64 + 1;
+    let params = CreateNftParams {
+        name: format!("Bonus #{}", next_index),
+        symbol: "BN".to_string(),
+        uri: "https://example.com/nft.json".to_string(), // заглушка для devnet-теста
+        index: next_index,
+        recipient: investor,
+    };
+
+    // ВАЖНО: mint_pda должен быть создан ТЕСТОМ заранее с decimals=0, mint_authority=signer, freeze_authority=signer.
+    create_nft_with_freeze(&ctx, params)?;
+
+    // 3) обновляем агрегаты очереди (минимально: увеличим счётчик и сумму бонусов)
+    st.q1_tokens = st.q1_tokens.saturating_add(1);
+    let add = u32::try_from(core::cmp::min(amount, u64::from(u32::MAX))).unwrap_or(u32::MAX);
+    st.sum1_bonus = st.sum1_bonus.saturating_add(add);
+
+    // 4) сохраняем
+    write_state_to_pda(&ctx.accounts.state_pda.to_account_info(), &st)?;
+    Ok(())
+}
+
+/// ------------------------------------------
+/// claim: «выплата».
+/// По заданию: читаем в начале, сохраняем в конце.
+/// ------------------------------------------
+pub fn claim(ctx: Context) -> Result<()> {
+    // 1) читаем
+    let mut st = read_state_from_pda(&ctx.accounts.state_pda.to_account_info())?;
+
+    // --- тут твоя логика списаний/выплат ---
+    let _ = &mut st; // заглушка
+
+    // 2) сохраняем
+    write_state_to_pda(&ctx.accounts.state_pda.to_account_info(), &st)?;
+    Ok(())
+}
+
+
+
+
+
+//todo
+
+
+
+
+
+/// ==============================================
+/// Коды ошибок (берём из твоего блока; можно расширять)
+/// ==============================================
+
+#[error_code]
+pub enum ErrCode {
+    /// Система уже инициализирована и не может быть инициализирована повторно!
+    #[msg("Система уже инициализирована и не может быть инициализирована повторно!")]
+    SystemAlreadyInitialized = 1000,
+
+    #[msg("PDA не содержит данных или не инициализирован")]
+    EmptyPdaData = 1002,
+
+    #[msg("Пользователь уже зарегистрирован")]
+    UserAlreadyExists = 1003,
+
+    #[msg("Некорректный логин")]
+    InvalidLogin = 1004,
+
+    #[msg("Не совпадает PDA адрес")]
+    InvalidPdaAddress = 1006,
+
+    #[msg("Формат данных не поддерживается")]
+    UnsupportedFormat = 1011,
+
+    #[msg("Ошибка при десериализации")]
+    DeserializationError = 1012,
+
+    /// PDA уже существует, создание невозможно
+    #[msg("PDA-аккаунт уже существует и не может быть создан повторно.")]
+    PdaAlreadyExists = 1009,
+
+    #[msg("Подписавший не совпадает с ожидаемым пользователем (временное ограничение)")]
+    InvalidSigner = 1005,
+
+    /// Не получилось создать пользователя
+    #[msg("Не получилось создать пользователя, система уже перегружена, попробуйте позже!")]
+    NoSuitableIdPda = 1010,
+}
+
+
+
+
+
+use anchor_lang::prelude::*;
+
+/// ================================
+/// КОНСТАНТЫ ФОРМАТА / ДЛИНЫ ДАННЫХ
+/// ================================
+
+/// Версия формата хранения состояния.
+/// Мы жёстко фиксируем «1», чтобы код мог отличать будущие версии.
+pub const INVEST_STATE_FORMAT_V1: u32 = 1;
+
+/// Сырые данные состояния V1 занимают ровно 6 * 4 = 24 байта.
+pub const INVEST_STATE_RAW_LEN_V1: usize = 24; // байт
+
+/// ================================
+/// ОПИСАНИЕ СТРУКТУРЫ СОСТОЯНИЯ (V1)
+/// ================================
+#[derive(Clone, Copy, Debug, Default)]
+pub struct InvestState {
+    pub format: u32,
+    pub coef: u32,
+    pub q1_tokens: u32,
+    pub sum1_bonus: u32,
+    pub q1_paid_tokens: u32,
+    pub sum1_paid_bonus: u32,
+}
+
+/// ========================================
+/// СЕРИАЛИЗАЦИЯ (структура -> массив байт)
+/// ========================================
+pub fn serialize_invest_state_v1(s: &InvestState) -> Vec {
+    let mut out = Vec::with_capacity(INVEST_STATE_RAW_LEN_V1);
+    out.extend_from_slice(&INVEST_STATE_FORMAT_V1.to_le_bytes()); // [0..4)
+    out.extend_from_slice(&s.coef.to_le_bytes());            // [4..8)
+    out.extend_from_slice(&s.q1_tokens.to_le_bytes());       // [8..12)
+    out.extend_from_slice(&s.sum1_bonus.to_le_bytes());      // [12..16)
+    out.extend_from_slice(&s.q1_paid_tokens.to_le_bytes());  // [16..20)
+    out.extend_from_slice(&s.sum1_paid_bonus.to_le_bytes()); // [20..24)
+    debug_assert_eq!(out.len(), INVEST_STATE_RAW_LEN_V1);
+    out
+}
+
+/// ===========================================
+/// ДЕСЕРИАЛИЗАЦИЯ (массив байт -> структура)
+/// ===========================================
+pub fn deserialize_invest_state(data: &[u8]) -> Result {
+    if data.len() < INVEST_STATE_RAW_LEN_V1 {
+        return Err(error!(ErrCode::DeserializationError));
+    }
+    fn read_u32_le(slice: &[u8], start: usize) -> u32 {
+        let bytes: [u8; 4] = slice[start..start + 4]
+            .try_into()
+            .expect("slice has enough length due to pre-check");
+        u32::from_le_bytes(bytes)
+    }
+    let format = read_u32_le(data, 0);
+    if format != INVEST_STATE_FORMAT_V1 {
+        return Err(error!(ErrCode::UnsupportedFormat));
+    }
+    let coef            = read_u32_le(data, 4);
+    let q1_tokens       = read_u32_le(data, 8);
+    let sum1_bonus      = read_u32_le(data, 12);
+    let q1_paid_tokens  = read_u32_le(data, 16);
+    let sum1_paid_bonus = read_u32_le(data, 20);
+
+    Ok(InvestState { format, coef, q1_tokens, sum1_bonus, q1_paid_tokens, sum1_paid_bonus })
+}
diff --git a/shine/programs/shine_payments/src/lib.rs b/shine/programs/shine_payments/src/lib.rs
new file mode 100644
index 0000000..aa1bfee
--- /dev/null
+++ b/shine/programs/shine_payments/src/lib.rs
@@ -0,0 +1,158 @@
+use anchor_lang::prelude::*;
+
+declare_id!("6Hes38UKFGF8cfQDQDVWoMGcSzGMUAgamWG31hCVhyPY");
+
+
+/// Подключаем модуль с полной реализацией.
+pub mod investments;
+use investments::*; // импортируем всё в корень
+
+// === модуль NFT ===
+pub mod nft;
+
+// ==============================================
+// Константы формата / сидов / размеров
+// ==============================================
+
+/// Префикс (seed) для PDA, где храним глобальное состояние выплат.
+/// Важно: сид — это просто набор байт; здесь он фиксированный.
+pub const PDA_SEED_PREFIX: &[u8] = b"shine_investments_state";
+
+/// Значение коэффициента «по умолчанию» при инициализации.
+pub const DEFAULT_COEF: u32 = 10; // ← «коэффициент» = 10 при init
+
+/// Ровно столько байт резервируем под PDA-данные.
+/// (Можно добавить запас на будущее, но по заданию — только 28.)
+pub const PAY_STATE_SPACE: u64 = 50; // просто сделал с запасом
+
+// ==============================================
+// Программа
+// ==============================================
+
+#[program]
+pub mod shine_payments {
+    use super::*;
+    // Явно подтягиваем типы и функции, чтобы не было путаницы после предыдущих ошибок парсера
+    use crate::investments::{Init, UseState};
+    use crate::investments::{
+        add_bonus as inv_add_bonus, claim as inv_claim, init as inv_init, invest as inv_invest,
+        ErrCode,
+    };
+
+    /// init — создаёт PDA и кладёт дефолтное состояние.
+    pub fn init(ctx: Context) -> Result<()> {
+        inv_init(ctx)
+    }
+
+    /// invest — в начале читает состояние, в конце сохраняет (логика внутри модуля).
+    pub fn invest(ctx: Context, amount: u64) -> Result<()> {
+        inv_invest(ctx, amount)
+    }
+
+    /// add_bonus — начисление бонусов (обычно от DAO).
+    /// Для NFT используем расширенный контекст AddBonusCtx (с аккаунтами коллекции и т.п.).
+    pub fn add_bonus(ctx: Context, investor: Pubkey, amount: u64) -> Result<()> {
+        inv_add_bonus(ctx, investor, amount)
+    }
+
+    /// claim — выплата.
+    pub fn claim(ctx: Context) -> Result<()> {
+        inv_claim(ctx)
+    }
+
+    /// ВРЕМЕННАЯ ФУНКЦИЯ только для тестов (в итоговой версии её не будет):
+    /// deleteInit — удалить PDA из init и вернуть ренту подписанту.
+    pub fn delete_init(ctx: Context) -> Result<()> {
+        let program_id = ctx.program_id;
+
+        // PDA по тем же сид/бамп, что и в init
+        let (expected_pda, _bump) = Pubkey::find_program_address(&[PDA_SEED_PREFIX], program_id);
+        require_keys_eq!(
+            expected_pda,
+            ctx.accounts.state_pda.key(),
+            ErrCode::InvalidPdaAddress
+        );
+
+        // Рента уйдёт на счёт подписанта (signer)
+        common::utils::delete_pda_return_rent(
+            &ctx.accounts.state_pda.to_account_info(),
+            &ctx.accounts.signer.to_account_info(),
+            program_id,
+        )
+    }
+}
+
+// ==============================================
+// Контексты вне #[program]
+// ==============================================
+
+/// Контекст для deleteInit (временный для тестов)
+#[derive(Accounts)]
+pub struct DeleteInit<'info> {
+    /// Подписант транзакции — ПОЛУЧАТЕЛЬ ренты
+    #[account(mut)]
+    pub signer: Signer<'info>,
+
+    /// Тот самый PDA из init
+    /// CHECK: адрес валидируем в хендлере по сид-у
+    #[account(mut)]
+    pub state_pda: UncheckedAccount<'info>,
+
+    /// Системная программа
+    pub system_program: Program<'info, System>,
+}
+
+/// Контекст для add_bonus: полный набор аккаунтов для операций с NFT и коллекцией.
+/// (Комменты по стилю проекта оставлены.)
+#[derive(Accounts)]
+pub struct AddBonusCtx<'info> {
+    /// Любой платящий/подписант (в реальном коде — свои проверки).
+    #[account(mut)]
+    pub signer: Signer<'info>,
+
+    /// Тот же PDA с состоянием (должен уже существовать).
+    /// CHECK: проверяется вручную по адресу
+    #[account(mut)]
+    pub state_pda: UncheckedAccount<'info>,
+
+    // --- аккаунты минтимого NFT ---
+    /// Mint создаваемого NFT (должен быть создан заранее: decimals=0, mint_authority=signer, freeze_authority=signer)
+    /// CHECK
+    #[account(mut)]
+    pub mint_pda: UncheckedAccount<'info>,
+
+    /// ATA получателя (может быть предсоздан тестом)
+    /// CHECK
+    #[account(mut)]
+    pub recipient_ata: UncheckedAccount<'info>,
+    /// Владелец ATA (инвестор)
+    /// CHECK
+    pub recipient_owner: UncheckedAccount<'info>,
+
+    // --- аккаунты коллекции (уже созданной заранее) ---
+    /// CHECK
+    pub collection_mint: UncheckedAccount<'info>,
+    /// CHECK
+    #[account(mut)]
+    pub collection_metadata_pda: UncheckedAccount<'info>,
+    /// CHECK
+    #[account(mut)]
+    pub collection_master_edition_pda: UncheckedAccount<'info>,
+    /// Апдейтер коллекции (update authority)
+    pub collection_update_authority: Signer<'info>,
+
+    // --- metadata + master edition для создаваемого NFT ---
+    /// CHECK
+    #[account(mut)]
+    pub metadata_pda: UncheckedAccount<'info>,
+    /// CHECK
+    #[account(mut)]
+    pub master_edition_pda: UncheckedAccount<'info>,
+
+    // --- программы ---
+    /// CHECK: проверяется по ID внутри nft.rs
+    pub token_metadata_program: UncheckedAccount<'info>,
+    pub token_program: Program<'info, anchor_spl::token::Token>,
+    pub associated_token_program: Program<'info, anchor_spl::associated_token::AssociatedToken>,
+    pub system_program: Program<'info, System>,
+}
diff --git a/shine/programs/shine_payments/src/nft.rs b/shine/programs/shine_payments/src/nft.rs
new file mode 100644
index 0000000..f78fa9c
--- /dev/null
+++ b/shine/programs/shine_payments/src/nft.rs
@@ -0,0 +1,190 @@
+use anchor_lang::prelude::*;
+use anchor_lang::solana_program::{program::invoke, program::invoke_signed};
+use anchor_spl::{associated_token::AssociatedToken, token::Token};
+
+use mpl_token_metadata::{
+    ID as TM_ID,
+    instructions::{
+        CreateMasterEditionV3Builder,
+        CreateMetadataAccountV3Builder,
+        SetAndVerifySizedCollectionItemBuilder,
+    },
+    types::{Collection, Creator, DataV2, Uses, UseMethod},
+};
+
+use spl_token::instruction as spl_ix;
+
+/// Параметры для минта NFT
+#[derive(Clone)]
+pub struct CreateNftParams {
+    pub name: String,
+    pub symbol: String,
+    pub uri: String,
+    pub index: u64,
+    pub recipient: Pubkey,
+}
+
+/// Создание metadata, чеканка 1 токена, freeze ATA, создание master edition, verify в коллекции.
+pub fn create_nft_with_freeze(
+    ctx: &Context,
+    params: CreateNftParams,
+) -> Result<()> {
+    let a = &ctx.accounts;
+
+    // Проверяем что это именно программа Metaplex Token Metadata
+    require_keys_eq!(a.token_metadata_program.key(), TM_ID, CustomError::InvalidMetadataProgram);
+
+    // 1) Создание Metadata для нового NFT
+    let creators = Some(vec![Creator {
+        address: a.collection_update_authority.key(),
+        verified: true,
+        share: 100,
+    }]);
+
+    let data = DataV2 {
+        name: truncate(¶ms.name, 32),
+        symbol: truncate(¶ms.symbol, 10),
+        uri: truncate(¶ms.uri, 256),
+        seller_fee_basis_points: 0,
+        creators,
+        collection: Some(Collection {
+            verified: false, // отметим как часть коллекции позже через verify
+            key: a.collection_mint.key(),
+        }),
+        uses: Some(Uses {
+            use_method: UseMethod::Burn,
+            remaining: 1,
+            total: 1,
+        }),
+    };
+
+    // В mpl-token-metadata v5 update_authority(pubkey, is_signer: bool)
+    let ix_md = CreateMetadataAccountV3Builder::new()
+        .metadata(a.metadata_pda.key())
+        .mint(a.mint_pda.key())
+        .mint_authority(a.signer.key())
+        .payer(a.signer.key())
+        .update_authority(a.collection_update_authority.key(), true)
+        .system_program(a.system_program.key())
+        .data(data)
+        .is_mutable(true)
+        .instruction();
+
+    invoke_signed(
+        &ix_md,
+        &[
+            a.metadata_pda.to_account_info(),
+            a.mint_pda.to_account_info(),
+            a.signer.to_account_info(),
+            a.collection_update_authority.to_account_info(),
+            a.system_program.to_account_info(),
+            a.token_metadata_program.to_account_info(),
+        ],
+        &[],
+    )?;
+
+    // 2) Чеканим 1 токен на ATA получателя
+    let ix_mint_to = spl_ix::mint_to(
+        &a.token_program.key(),
+        &a.mint_pda.key(),
+        &a.recipient_ata.key(),
+        &a.signer.key(),
+        &[],
+        1,
+    )?;
+    invoke(
+        &ix_mint_to,
+        &[
+            a.mint_pda.to_account_info(),
+            a.recipient_ata.to_account_info(),
+            a.signer.to_account_info(),
+            a.token_program.to_account_info(),
+        ],
+    )?;
+
+    // 3) Замораживаем ATA получателя (freeze authority = signer)
+    let ix_freeze = spl_ix::freeze_account(
+        &a.token_program.key(),
+        &a.recipient_ata.key(),
+        &a.mint_pda.key(),
+        &a.signer.key(),
+        &[],
+    )?;
+    invoke(
+        &ix_freeze,
+        &[
+            a.recipient_ata.to_account_info(),
+            a.mint_pda.to_account_info(),
+            a.signer.to_account_info(),
+            a.token_program.to_account_info(),
+        ],
+    )?;
+
+    // 4) Создаём Master Edition
+    let ix_me = CreateMasterEditionV3Builder::new()
+        .edition(a.master_edition_pda.key())
+        .mint(a.mint_pda.key())
+        .update_authority(a.collection_update_authority.key())
+        .mint_authority(a.signer.key())
+        .payer(a.signer.key())
+        .metadata(a.metadata_pda.key())
+        .token_program(a.token_program.key())
+        .system_program(a.system_program.key())
+        .max_supply(0)
+        .instruction();
+
+    invoke_signed(
+        &ix_me,
+        &[
+            a.master_edition_pda.to_account_info(),
+            a.mint_pda.to_account_info(),
+            a.collection_update_authority.to_account_info(),
+            a.signer.to_account_info(),
+            a.metadata_pda.to_account_info(),
+            a.token_program.to_account_info(),
+            a.system_program.to_account_info(),
+            a.token_metadata_program.to_account_info(),
+        ],
+        &[],
+    )?;
+
+    // 5) Verify как часть коллекции
+    // Метод называется collection_master_edition_account(...)
+    let ix_verify = SetAndVerifySizedCollectionItemBuilder::new()
+        .metadata(a.metadata_pda.key())
+        .collection_authority(a.collection_update_authority.key())
+        .payer(a.signer.key())
+        .update_authority(a.collection_update_authority.key())
+        .collection_mint(a.collection_mint.key())
+        .collection(a.collection_metadata_pda.key())
+        .collection_master_edition_account(a.collection_master_edition_pda.key())
+        .instruction();
+
+    invoke_signed(
+        &ix_verify,
+        &[
+            a.metadata_pda.to_account_info(),
+            a.collection_update_authority.to_account_info(),
+            a.signer.to_account_info(),
+            a.collection_update_authority.to_account_info(),
+            a.collection_mint.to_account_info(),
+            a.collection_metadata_pda.to_account_info(),
+            a.collection_master_edition_pda.to_account_info(),
+            a.token_metadata_program.to_account_info(),
+        ],
+        &[],
+    )?;
+
+    msg!("NFT создан, заморожен, мастер-издание создано и верифицировано в коллекции (index={})", params.index);
+    Ok(())
+}
+
+fn truncate(s: &str, max: usize) -> String {
+    if s.len() <= max { s.to_string() } else { s.chars().take(max).collect() }
+}
+
+#[error_code]
+pub enum CustomError {
+    #[msg("Invalid Token Metadata program account")]
+    InvalidMetadataProgram,
+}
diff --git a/shine/programs/shine_users/Cargo.toml b/shine/programs/shine_users/Cargo.toml
new file mode 100644
index 0000000..0406bdc
--- /dev/null
+++ b/shine/programs/shine_users/Cargo.toml
@@ -0,0 +1,30 @@
+[package]
+name = "shine_users"
+version = "0.1.0"
+description = "User registration smart contract"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib", "lib"]
+name = "shine_users"
+test = false
+doctest = false
+bench = false
+
+[dependencies]
+anchor-lang = "0.31.1"
+common = { path = "../common" }
+ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"] }
+sha2 = "0.10"
+
+
+[features]
+default = []
+no-entrypoint = []
+no-idl = []
+no-log-ix-name = []
+anchor-debug = []
+custom-heap = []
+custom-panic = []
+cpi = []
+idl-build = ["anchor-lang/idl-build"]
diff --git a/shine/programs/shine_users/src/lib.rs b/shine/programs/shine_users/src/lib.rs
new file mode 100644
index 0000000..d9829b5
--- /dev/null
+++ b/shine/programs/shine_users/src/lib.rs
@@ -0,0 +1,23 @@
+use anchor_lang::prelude::*;
+
+pub mod users;
+pub mod settings;
+
+use users::*;
+
+
+declare_id!("5dFcWDNp42Xn9Vv4oDMJzM4obBJ8hvDuAtPX54fT5L3t");
+
+
+#[program]
+pub mod shine {
+    use super::*;
+
+    pub fn create_user_pda(ctx: Context, args: CreateUserPdaArgs) -> Result<()> {
+        users::create_user_pda(ctx, args)
+    }
+
+    pub fn update_user_pda(ctx: Context, args: UpdateUserPdaArgs) -> Result<()> {
+        users::update_user_pda(ctx, args)
+    }
+}
diff --git a/shine/programs/shine_users/src/settings.rs b/shine/programs/shine_users/src/settings.rs
new file mode 100644
index 0000000..e1b8bfe
--- /dev/null
+++ b/shine/programs/shine_users/src/settings.rs
@@ -0,0 +1,12 @@
+pub const USER_PDA_SEED_PREFIX: &str = "login=";
+// Увеличили размер PDA, чтобы оставить запас под будущие расширения формата
+// (в частности, сценарии ротации root key с дополнительной подписью старого ключа).
+pub const USER_PDA_SPACE: usize = 768;
+
+pub const REGISTRATION_FEE_RECEIVER: &str = "6bFc5Gz5qF172GQhK5HpDbWs8F6qcSxdHn5XqAstf1fY";
+pub const REGISTRATION_FEE_LAMPORTS: u64 = 10_000_000; // 0.01 SOL
+
+pub const LIMIT_STEP: u64 = 10_000;
+pub const LAMPORTS_PER_LIMIT_STEP: u64 = 100_000; // 0.0001 SOL за 10_000 лимита
+
+pub const START_BONUS_LIMIT: u64 = 100_000;
diff --git a/shine/programs/shine_users/src/users.rs b/shine/programs/shine_users/src/users.rs
new file mode 100644
index 0000000..7f0585f
--- /dev/null
+++ b/shine/programs/shine_users/src/users.rs
@@ -0,0 +1,592 @@
+use crate::settings;
+use anchor_lang::prelude::*;
+use anchor_lang::solana_program::{program::invoke, system_instruction};
+use common::utils::{create_pda, safe_read_pda, write_to_pda, ErrCode};
+use ed25519_dalek::{PublicKey, Signature, Verifier};
+use sha2::{Digest, Sha256};
+use std::str::FromStr;
+
+const MAGIC: &[u8; 5] = b"SHiNE";
+const FORMAT_MAJOR: u8 = 1;
+const FORMAT_MINOR: u8 = 0;
+const RESERVED_BYTES: [u8; 5] = [0, 0, 0, 0, 0];
+const ZERO_HASH: [u8; 32] = [0; 32];
+
+#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
+pub struct UserMutableFields {
+    pub blockchain_key: Pubkey,
+    pub device_key: Pubkey,
+    pub chain_number: u16,
+    pub is_server: bool,
+    pub server_key: Pubkey,
+    pub server_address: String,
+    pub connection_servers: Vec,
+    pub trusted_count: u8,
+}
+
+#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
+pub struct CreateUserPdaArgs {
+    pub login: String,
+    pub root_key: Pubkey,
+    pub created_at_ms: u64,
+    pub additional_limit: u64,
+    pub fields: UserMutableFields,
+    pub signature: Vec,
+}
+
+#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
+pub struct UpdateUserPdaArgs {
+    pub login: String,
+    pub root_key: Pubkey,
+    pub created_at_ms: u64,
+    pub updated_at_ms: u64,
+    pub version: u32,
+    pub prev_hash: Vec,
+    pub additional_limit: u64,
+    pub fields: UserMutableFields,
+    pub signature: Vec,
+}
+
+pub struct UserRecord {
+    pub created_at_ms: u64,
+    pub updated_at_ms: u64,
+    pub version: u32,
+    pub prev_hash: [u8; 32],
+    pub login: String,
+    pub root_key: Pubkey,
+    pub blockchain_key: Pubkey,
+    pub device_key: Pubkey,
+    pub chain_number: u16,
+    pub balance: u64,
+    pub is_server: bool,
+    pub server_key: Pubkey,
+    pub server_address: String,
+    pub connection_servers: Vec,
+    pub trusted_count: u8,
+    pub signature: [u8; 64],
+}
+
+#[derive(Accounts)]
+pub struct CreateUserPda<'info> {
+    /// CHECK: подписант транзакции, валидируется Anchor как signer и mut.
+    #[account(mut, signer)]
+    pub signer: AccountInfo<'info>,
+    /// CHECK: PDA пользователя, адрес проверяется вручную через seed в обработчике.
+    #[account(mut)]
+    pub user_pda: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
+    /// CHECK: адрес получателя комиссии проверяется вручную с константой settings.
+    #[account(mut)]
+    pub fee_receiver: AccountInfo<'info>,
+}
+
+#[derive(Accounts)]
+pub struct UpdateUserPda<'info> {
+    /// CHECK: подписант транзакции, валидируется Anchor как signer и mut.
+    #[account(mut, signer)]
+    pub signer: AccountInfo<'info>,
+    /// CHECK: PDA пользователя, адрес проверяется вручную через seed в обработчике.
+    #[account(mut)]
+    pub user_pda: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
+    /// CHECK: адрес получателя комиссии проверяется вручную с константой settings.
+    #[account(mut)]
+    pub fee_receiver: AccountInfo<'info>,
+}
+
+pub fn create_user_pda(ctx: Context, args: CreateUserPdaArgs) -> Result<()> {
+    validate_login(&args.login)?;
+    validate_fields(&args.fields)?;
+    validate_fee_receiver(&ctx.accounts.fee_receiver)?;
+    require!(
+        args.additional_limit % settings::LIMIT_STEP == 0,
+        ErrCode::InvalidLimitIncrement
+    );
+
+    let (expected_pda, bump) = find_user_pda(ctx.program_id, &args.login);
+    require_keys_eq!(
+        expected_pda,
+        ctx.accounts.user_pda.key(),
+        ErrCode::InvalidPdaAddress
+    );
+    require!(
+        ctx.accounts.user_pda.owner == &Pubkey::default(),
+        ErrCode::UserAlreadyExists
+    );
+
+    let start_balance = settings::START_BONUS_LIMIT
+        .checked_add(args.additional_limit)
+        .ok_or(error!(ErrCode::MathOverflow))?;
+
+    let mut record = UserRecord {
+        created_at_ms: args.created_at_ms,
+        updated_at_ms: args.created_at_ms,
+        version: 0,
+        prev_hash: ZERO_HASH,
+        login: args.login.clone(),
+        root_key: args.root_key,
+        blockchain_key: args.fields.blockchain_key,
+        device_key: args.fields.device_key,
+        chain_number: args.fields.chain_number,
+        balance: start_balance,
+        is_server: args.fields.is_server,
+        server_key: args.fields.server_key,
+        server_address: args.fields.server_address.clone(),
+        connection_servers: args.fields.connection_servers.clone(),
+        trusted_count: args.fields.trusted_count,
+        signature: [0; 64],
+    };
+
+    let unsigned = serialize_unsigned_record(&record)?;
+    verify_record_signature(&record.root_key, &args.signature, &unsigned)?;
+    record.signature = vec_to_signature(&args.signature)?;
+
+    let serialized = serialize_full_record(&record)?;
+    require!(
+        serialized.len() <= settings::USER_PDA_SPACE,
+        ErrCode::RecordTooLarge
+    );
+    let padded = pad_to_fixed_size(serialized, settings::USER_PDA_SPACE)?;
+
+    let pda_seeds: &[&[u8]] = &[
+        settings::USER_PDA_SEED_PREFIX.as_bytes(),
+        args.login.as_bytes(),
+        &[bump],
+    ];
+    create_pda(
+        &ctx.accounts.user_pda,
+        &ctx.accounts.signer,
+        &ctx.accounts.system_program.to_account_info(),
+        ctx.program_id,
+        pda_seeds,
+        settings::USER_PDA_SPACE as u64,
+    )?;
+    write_to_pda(&ctx.accounts.user_pda, &padded)?;
+
+    let total_fee = settings::REGISTRATION_FEE_LAMPORTS
+        .checked_add(limit_fee_lamports(args.additional_limit)?)
+        .ok_or(error!(ErrCode::MathOverflow))?;
+    transfer_lamports(
+        &ctx.accounts.signer,
+        &ctx.accounts.fee_receiver,
+        &ctx.accounts.system_program.to_account_info(),
+        total_fee,
+    )?;
+
+    Ok(())
+}
+
+pub fn update_user_pda(ctx: Context, args: UpdateUserPdaArgs) -> Result<()> {
+    validate_login(&args.login)?;
+    validate_fields(&args.fields)?;
+    validate_fee_receiver(&ctx.accounts.fee_receiver)?;
+    require!(
+        args.additional_limit % settings::LIMIT_STEP == 0,
+        ErrCode::InvalidLimitIncrement
+    );
+
+    let (expected_pda, _) = find_user_pda(ctx.program_id, &args.login);
+    require_keys_eq!(
+        expected_pda,
+        ctx.accounts.user_pda.key(),
+        ErrCode::InvalidPdaAddress
+    );
+    require!(
+        ctx.accounts.user_pda.owner == ctx.program_id,
+        ErrCode::InvalidPdaAddress
+    );
+
+    let raw = safe_read_pda(&ctx.accounts.user_pda);
+    require!(!raw.is_empty(), ErrCode::EmptyPdaData);
+    let old_record = deserialize_record_from_pda(&raw)?;
+
+    require!(
+        old_record.login == args.login,
+        ErrCode::ImmutableFieldChanged
+    );
+    require!(
+        old_record.created_at_ms == args.created_at_ms,
+        ErrCode::ImmutableFieldChanged
+    );
+    require_keys_eq!(old_record.root_key, args.root_key, ErrCode::ImmutableFieldChanged);
+    require!(
+        args.version == old_record.version.saturating_add(1),
+        ErrCode::InvalidVersion
+    );
+
+    let expected_prev_hash = hash_unsigned_record(&old_record)?;
+    let provided_prev_hash = vec_to_hash32(&args.prev_hash)?;
+    require!(
+        expected_prev_hash == provided_prev_hash,
+        ErrCode::InvalidPrevHash
+    );
+
+    let new_balance = old_record
+        .balance
+        .checked_add(args.additional_limit)
+        .ok_or(error!(ErrCode::MathOverflow))?;
+    require!(new_balance >= old_record.balance, ErrCode::BalanceDecrease);
+
+    let mut new_record = UserRecord {
+        created_at_ms: old_record.created_at_ms,
+        updated_at_ms: args.updated_at_ms,
+        version: args.version,
+        prev_hash: provided_prev_hash,
+        login: old_record.login.clone(),
+        root_key: old_record.root_key,
+        blockchain_key: args.fields.blockchain_key,
+        device_key: args.fields.device_key,
+        chain_number: args.fields.chain_number,
+        balance: new_balance,
+        is_server: args.fields.is_server,
+        server_key: args.fields.server_key,
+        server_address: args.fields.server_address.clone(),
+        connection_servers: args.fields.connection_servers.clone(),
+        trusted_count: args.fields.trusted_count,
+        signature: [0; 64],
+    };
+
+    let unsigned = serialize_unsigned_record(&new_record)?;
+    verify_record_signature(&new_record.root_key, &args.signature, &unsigned)?;
+    new_record.signature = vec_to_signature(&args.signature)?;
+
+    let serialized = serialize_full_record(&new_record)?;
+    require!(
+        serialized.len() <= settings::USER_PDA_SPACE,
+        ErrCode::RecordTooLarge
+    );
+    let padded = pad_to_fixed_size(serialized, settings::USER_PDA_SPACE)?;
+    write_to_pda(&ctx.accounts.user_pda, &padded)?;
+
+    let topup_fee = limit_fee_lamports(args.additional_limit)?;
+    if topup_fee > 0 {
+        transfer_lamports(
+            &ctx.accounts.signer,
+            &ctx.accounts.fee_receiver,
+            &ctx.accounts.system_program.to_account_info(),
+            topup_fee,
+        )?;
+    }
+
+    Ok(())
+}
+
+fn serialize_unsigned_record(record: &UserRecord) -> Result> {
+    let login_bytes = record.login.as_bytes();
+    require!(login_bytes.len() <= u8::MAX as usize, ErrCode::InvalidLogin);
+
+    let server_address_bytes = record.server_address.as_bytes();
+    require!(
+        server_address_bytes.len() <= u8::MAX as usize,
+        ErrCode::InvalidRecordData
+    );
+    require!(
+        record.connection_servers.len() <= u8::MAX as usize,
+        ErrCode::InvalidRecordData
+    );
+
+    let mut out = Vec::new();
+    out.extend_from_slice(MAGIC);
+    out.push(FORMAT_MAJOR);
+    out.push(FORMAT_MINOR);
+    out.extend_from_slice(&0u16.to_le_bytes());
+
+    out.extend_from_slice(&record.created_at_ms.to_le_bytes());
+    out.extend_from_slice(&record.updated_at_ms.to_le_bytes());
+    out.extend_from_slice(&record.version.to_le_bytes());
+    out.extend_from_slice(&record.prev_hash);
+
+    out.push(login_bytes.len() as u8);
+    out.extend_from_slice(login_bytes);
+
+    out.extend_from_slice(record.root_key.as_ref());
+    out.extend_from_slice(record.blockchain_key.as_ref());
+    out.extend_from_slice(record.device_key.as_ref());
+
+    out.extend_from_slice(&record.chain_number.to_le_bytes());
+    out.extend_from_slice(&record.balance.to_le_bytes());
+
+    out.push(if record.is_server { 1 } else { 0 });
+    if record.is_server {
+        out.extend_from_slice(record.server_key.as_ref());
+        out.push(server_address_bytes.len() as u8);
+        out.extend_from_slice(server_address_bytes);
+    }
+
+    out.push(record.connection_servers.len() as u8);
+    for login in &record.connection_servers {
+        let bytes = login.as_bytes();
+        require!(bytes.len() <= u8::MAX as usize, ErrCode::InvalidRecordData);
+        out.push(bytes.len() as u8);
+        out.extend_from_slice(bytes);
+    }
+
+    out.push(record.trusted_count);
+    out.extend_from_slice(&RESERVED_BYTES);
+
+    let record_len = out
+        .len()
+        .checked_add(64)
+        .ok_or(error!(ErrCode::MathOverflow))?;
+    require!(record_len <= u16::MAX as usize, ErrCode::RecordTooLarge);
+    let len_bytes = (record_len as u16).to_le_bytes();
+    out[7] = len_bytes[0];
+    out[8] = len_bytes[1];
+
+    Ok(out)
+}
+
+fn serialize_full_record(record: &UserRecord) -> Result> {
+    let mut out = serialize_unsigned_record(record)?;
+    out.extend_from_slice(&record.signature);
+    Ok(out)
+}
+
+fn deserialize_record_from_pda(raw: &[u8]) -> Result {
+    require!(raw.len() >= 9, ErrCode::InvalidRecordData);
+    require!(&raw[0..5] == MAGIC, ErrCode::InvalidRecordMagic);
+    require!(
+        raw[5] == FORMAT_MAJOR && raw[6] == FORMAT_MINOR,
+        ErrCode::InvalidRecordFormat
+    );
+
+    let record_len = u16::from_le_bytes([raw[7], raw[8]]) as usize;
+    require!(record_len >= 9 + 64, ErrCode::InvalidRecordLength);
+    require!(record_len <= raw.len(), ErrCode::InvalidRecordLength);
+
+    let useful = &raw[..record_len];
+    let mut cursor = 9usize;
+
+    let created_at_ms = read_u64(useful, &mut cursor)?;
+    let updated_at_ms = read_u64(useful, &mut cursor)?;
+    let version = read_u32(useful, &mut cursor)?;
+    let prev_hash = read_fixed_32(useful, &mut cursor)?;
+    let login = read_len_prefixed_string(useful, &mut cursor)?;
+
+    let root_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
+    let blockchain_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
+    let device_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
+
+    let chain_number = read_u16(useful, &mut cursor)?;
+    let balance = read_u64(useful, &mut cursor)?;
+
+    let is_server = read_u8(useful, &mut cursor)? == 1;
+    let (server_key, server_address) = if is_server {
+        (
+            Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?),
+            read_len_prefixed_string(useful, &mut cursor)?,
+        )
+    } else {
+        (Pubkey::default(), String::new())
+    };
+
+    let connections_count = read_u8(useful, &mut cursor)? as usize;
+    let mut connection_servers = Vec::with_capacity(connections_count);
+    for _ in 0..connections_count {
+        connection_servers.push(read_len_prefixed_string(useful, &mut cursor)?);
+    }
+
+    let trusted_count = read_u8(useful, &mut cursor)?;
+    require!(
+        useful.get(cursor..cursor + 5) == Some(&RESERVED_BYTES),
+        ErrCode::InvalidRecordData
+    );
+    cursor += 5;
+
+    let signature = read_fixed_64(useful, &mut cursor)?;
+    require!(cursor == useful.len(), ErrCode::InvalidRecordLength);
+
+    Ok(UserRecord {
+        created_at_ms,
+        updated_at_ms,
+        version,
+        prev_hash,
+        login,
+        root_key,
+        blockchain_key,
+        device_key,
+        chain_number,
+        balance,
+        is_server,
+        server_key,
+        server_address,
+        connection_servers,
+        trusted_count,
+        signature,
+    })
+}
+
+fn hash_unsigned_record(record: &UserRecord) -> Result<[u8; 32]> {
+    let unsigned = serialize_unsigned_record(record)?;
+    let digest = Sha256::digest(unsigned);
+    let mut out = [0u8; 32];
+    out.copy_from_slice(&digest);
+    Ok(out)
+}
+
+fn verify_record_signature(root_key: &Pubkey, signature: &[u8], unsigned: &[u8]) -> Result<()> {
+    let sig_arr = vec_to_signature(signature)?;
+    let hash = Sha256::digest(unsigned);
+    let verify_key =
+        PublicKey::from_bytes(root_key.as_ref()).map_err(|_| error!(ErrCode::InvalidSignature))?;
+    let sig = Signature::from_bytes(&sig_arr).map_err(|_| error!(ErrCode::InvalidSignature))?;
+    verify_key
+        .verify(hash.as_slice(), &sig)
+        .map_err(|_| error!(ErrCode::InvalidSignature))?;
+    Ok(())
+}
+
+fn validate_login(login: &str) -> Result<()> {
+    require!(!login.is_empty(), ErrCode::InvalidLogin);
+    require!(login.len() <= 30, ErrCode::InvalidLogin);
+    for ch in login.chars() {
+        if !(ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_') {
+            return Err(error!(ErrCode::InvalidLogin));
+        }
+    }
+    Ok(())
+}
+
+fn validate_fields(fields: &UserMutableFields) -> Result<()> {
+    if fields.is_server {
+        require!(!fields.server_address.is_empty(), ErrCode::InvalidRecordData);
+        require!(
+            fields.server_address.as_bytes().len() <= u8::MAX as usize,
+            ErrCode::InvalidRecordData
+        );
+    } else {
+        require!(fields.server_address.is_empty(), ErrCode::InvalidRecordData);
+    }
+    require!(
+        fields.connection_servers.len() <= u8::MAX as usize,
+        ErrCode::InvalidRecordData
+    );
+    for login in &fields.connection_servers {
+        require!(!login.is_empty(), ErrCode::InvalidRecordData);
+        require!(login.as_bytes().len() <= u8::MAX as usize, ErrCode::InvalidRecordData);
+    }
+    Ok(())
+}
+
+fn validate_fee_receiver(fee_receiver: &AccountInfo) -> Result<()> {
+    let expected = Pubkey::from_str(settings::REGISTRATION_FEE_RECEIVER)
+        .map_err(|_| error!(ErrCode::InvalidFeeReceiver))?;
+    require_keys_eq!(expected, *fee_receiver.key, ErrCode::InvalidFeeReceiver);
+    Ok(())
+}
+
+fn transfer_lamports<'info>(
+    payer: &AccountInfo<'info>,
+    recipient: &AccountInfo<'info>,
+    system_program: &AccountInfo<'info>,
+    lamports: u64,
+) -> Result<()> {
+    if lamports == 0 {
+        return Ok(());
+    }
+    let ix = system_instruction::transfer(payer.key, recipient.key, lamports);
+    invoke(&ix, &[payer.clone(), recipient.clone(), system_program.clone()])?;
+    Ok(())
+}
+
+fn limit_fee_lamports(limit_delta: u64) -> Result {
+    let units = limit_delta / settings::LIMIT_STEP;
+    units
+        .checked_mul(settings::LAMPORTS_PER_LIMIT_STEP)
+        .ok_or(error!(ErrCode::MathOverflow))
+}
+
+fn find_user_pda(program_id: &Pubkey, login: &str) -> (Pubkey, u8) {
+    Pubkey::find_program_address(
+        &[settings::USER_PDA_SEED_PREFIX.as_bytes(), login.as_bytes()],
+        program_id,
+    )
+}
+
+fn pad_to_fixed_size(mut bytes: Vec, target_size: usize) -> Result> {
+    require!(bytes.len() <= target_size, ErrCode::RecordTooLarge);
+    bytes.resize(target_size, 0);
+    Ok(bytes)
+}
+
+fn vec_to_signature(input: &[u8]) -> Result<[u8; 64]> {
+    require!(input.len() == 64, ErrCode::InvalidSignature);
+    let mut out = [0u8; 64];
+    out.copy_from_slice(input);
+    Ok(out)
+}
+
+fn vec_to_hash32(input: &[u8]) -> Result<[u8; 32]> {
+    require!(input.len() == 32, ErrCode::InvalidPrevHash);
+    let mut out = [0u8; 32];
+    out.copy_from_slice(input);
+    Ok(out)
+}
+
+fn read_u8(data: &[u8], cursor: &mut usize) -> Result {
+    let v = *data.get(*cursor).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor += 1;
+    Ok(v)
+}
+
+fn read_u16(data: &[u8], cursor: &mut usize) -> Result {
+    let end = cursor
+        .checked_add(2)
+        .ok_or(error!(ErrCode::InvalidRecordData))?;
+    let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor = end;
+    Ok(u16::from_le_bytes([slice[0], slice[1]]))
+}
+
+fn read_u32(data: &[u8], cursor: &mut usize) -> Result {
+    let end = cursor
+        .checked_add(4)
+        .ok_or(error!(ErrCode::InvalidRecordData))?;
+    let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor = end;
+    Ok(u32::from_le_bytes([slice[0], slice[1], slice[2], slice[3]]))
+}
+
+fn read_u64(data: &[u8], cursor: &mut usize) -> Result {
+    let end = cursor
+        .checked_add(8)
+        .ok_or(error!(ErrCode::InvalidRecordData))?;
+    let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor = end;
+    Ok(u64::from_le_bytes([
+        slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
+    ]))
+}
+
+fn read_fixed_32(data: &[u8], cursor: &mut usize) -> Result<[u8; 32]> {
+    let end = cursor
+        .checked_add(32)
+        .ok_or(error!(ErrCode::InvalidRecordData))?;
+    let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor = end;
+    let mut out = [0u8; 32];
+    out.copy_from_slice(slice);
+    Ok(out)
+}
+
+fn read_fixed_64(data: &[u8], cursor: &mut usize) -> Result<[u8; 64]> {
+    let end = cursor
+        .checked_add(64)
+        .ok_or(error!(ErrCode::InvalidRecordData))?;
+    let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor = end;
+    let mut out = [0u8; 64];
+    out.copy_from_slice(slice);
+    Ok(out)
+}
+
+fn read_len_prefixed_string(data: &[u8], cursor: &mut usize) -> Result {
+    let len = read_u8(data, cursor)? as usize;
+    let end = cursor
+        .checked_add(len)
+        .ok_or(error!(ErrCode::InvalidRecordData))?;
+    let slice = data.get(*cursor..end).ok_or(error!(ErrCode::InvalidRecordData))?;
+    *cursor = end;
+    let value = std::str::from_utf8(slice).map_err(|_| error!(ErrCode::InvalidRecordData))?;
+    Ok(value.to_string())
+}
diff --git a/shine/scripts/devnet/README.md b/shine/scripts/devnet/README.md
new file mode 100644
index 0000000..96d6e02
--- /dev/null
+++ b/shine/scripts/devnet/README.md
@@ -0,0 +1,76 @@
+Devnet E2E тест: NFT-модуль + add_bonus
+
+Ветка содержит скрипты для проверки (NFT + add_bonus) в devnet.
+
+Скрипты:
+
+quick_devnet_e2e.js — создаёт 1 NFT и вызывает add_bonus.
+
+quick_devnet_e2e_multi.js — создаёт N NFT в коллекции.
+
+
+
+Подготовка окружения
+
+Установите зависимости:
+
+npm i @coral-xyz/anchor @solana/web3.js @solana/spl-token
+
+
+Создайте файл .env с переменными:
+
+
+ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
+ANCHOR_WALLET=/Users//.config/solana/id.json
+PROGRAM_ID=qpgnAKhsXgPPaqQWfXhpme7UnG8GyStssuoSjF6Fzy3
+COLLECTION_MINT=
+
+ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
+ANCHOR_WALLET=/Users//.config/solana/id.json
+PROGRAM_ID=<адрес shine_payments в devnet>
+COLLECTION_MINT=
+
+
+Пополните кошелёк тестовыми SOL:
+
+solana config set --url https://api.devnet.solana.com
+solana airdrop 2
+
+Запуск тестов:
+
+одиночный NFT:
+
+node quick_devnet_e2e.js
+
+
+несколько NFT:
+
+node quick_devnet_e2e_multi.js 3
+
+
+
+Проверка результата
+
+В выводе будут строки:
+
+add_bonus() tx: 
+
+NFT mint: 
+ + + +Откройте транзакцию или mint в Solana Explorer + + +Убедитесь: + +Verified Collection совпадает с вашим COLLECTION_MINT + +У каждого NFT Supply = 1 + +Аккаунт получателя (ATA) помечен как frozen + + + + +⚠️ Повторный запуск может вернуть ошибку PdaAlreadyExists это нормально, так как PDA уже инициализирован. diff --git a/shine/scripts/devnet/quick_devnet_e2e.js b/shine/scripts/devnet/quick_devnet_e2e.js new file mode 100644 index 0000000..d981c13 --- /dev/null +++ b/shine/scripts/devnet/quick_devnet_e2e.js @@ -0,0 +1,285 @@ +const anchor = require("@coral-xyz/anchor"); +const { + Connection, + PublicKey, + SystemProgram, + Transaction, + TransactionInstruction, +} = require("@solana/web3.js"); +const { + getAssociatedTokenAddress, + createAssociatedTokenAccountInstruction, + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID, + createMint, + getAccount, +} = require("@solana/spl-token"); +const crypto = require("crypto"); + +// Адрес программы метаданных Metaplex (фиксированный) +const METAPLEX_TOKEN_METADATA_PROGRAM_ID = new PublicKey( + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" +); + +// ──────────────────────────────── +// Утилиты +// ──────────────────────────────── +const BASE58_RE = /[1-9A-HJ-NP-Za-km-z]{32,}/g; + +function mustEnv(name) { + const v = (process.env[name] || "").trim(); + if (!v) throw new Error(`Переменная окружения ${name} не задана`); + return v; +} + +function pickBase58(raw, name) { + const m = (raw || "").toString().match(BASE58_RE); + if (!m) throw new Error(`${name} не найден/невалиден: "${raw}"`); + return m[0]; +} + +// Anchor discriminator: sha256("global:") первые 8 байт +function disc8(ixName) { + const preimage = `global:${ixName}`; + const h = crypto.createHash("sha256").update(preimage).digest(); + return h.subarray(0, 8); +} + +function u64le(n) { + const bn = BigInt(n.toString()); + const buf = Buffer.alloc(8); + buf.writeBigUInt64LE(bn); + return buf; +} + +// Надёжная отправка транзакций с ретраями при «Blockhash not found» +async function sendTx(provider, tx, signers = []) { + const conn = provider.connection; + let lastErr; + + for (let attempt = 0; attempt < 3; attempt++) { + try { + const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash( + "confirmed" + ); + tx.recentBlockhash = blockhash; + tx.feePayer = provider.wallet.publicKey; + + for (const s of signers) tx.partialSign(s); + + const signed = await provider.wallet.signTransaction(tx); + + const sig = await conn.sendRawTransaction(signed.serialize(), { + skipPreflight: false, + preflightCommitment: "confirmed", + maxRetries: 3, + }); + + await conn.confirmTransaction( + { signature: sig, blockhash, lastValidBlockHeight }, + "confirmed" + ); + + return sig; + } catch (e) { + lastErr = e; + const msg = String(e?.message || e).toLowerCase(); + if (msg.includes("blockhash not found") || msg.includes("expired")) { + // пробуем ещё раз со свежим blockhash + continue; + } + throw e; + } + } + + throw lastErr; +} + +// ──────────────────────────────── +// Основной сценарий +// ──────────────────────────────── +(async () => { + // Провайдер / окружение + const RPC = mustEnv("ANCHOR_PROVIDER_URL"); + const WALLET_PATH = mustEnv("ANCHOR_WALLET"); + const PROGRAM_ID = new PublicKey( + pickBase58(mustEnv("PROGRAM_ID"), "PROGRAM_ID") + ); + const COLLECTION_MINT = new PublicKey( + pickBase58(mustEnv("COLLECTION_MINT"), "COLLECTION_MINT") + ); + + const provider = anchor.AnchorProvider.env(); // читает из ENV + anchor.setProvider(provider); + const conn = provider.connection; + const wallet = provider.wallet; + + console.log("────────────────────────────────────────────────────────"); + console.log("RPC :", RPC); + console.log("Wallet :", wallet.publicKey.toBase58()); + console.log("Program ID :", PROGRAM_ID.toBase58()); + console.log("Collection mint :", COLLECTION_MINT.toBase58()); + console.log( + "TokenMetadata PID :", + METAPLEX_TOKEN_METADATA_PROGRAM_ID.toBase58() + ); + console.log("ATA Program PID :", ASSOCIATED_TOKEN_PROGRAM_ID.toBase58()); + console.log("────────────────────────────────────────────────────────"); + + // 1) INIT (создаёт PDA состояния) + const [statePda] = PublicKey.findProgramAddressSync( + [Buffer.from("shine_investments_state")], + PROGRAM_ID + ); + + const initIx = new TransactionInstruction({ + programId: PROGRAM_ID, + keys: [ + { pubkey: wallet.publicKey, isSigner: true, isWritable: true }, // payer + { pubkey: statePda, isSigner: false, isWritable: true }, // state_pda + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + data: Buffer.from([...disc8("init")]), // без аргументов + }); + + try { + const sigInit = await sendTx(provider, new Transaction().add(initIx)); + console.log( + "init() tx:", + sigInit, + `https://explorer.solana.com/tx/${sigInit}?cluster=devnet` + ); + } catch (e) { + console.log("init(): возможно уже выполнен ->", e.message); + } + + // 2) Локально создаём mint нового NFT и ATA получателя + const mintPubkey = await createMint( + conn, + wallet.payer, + wallet.publicKey, + wallet.publicKey, + 0 + ); + console.log("NFT mint:", mintPubkey.toBase58()); + + const recipientOwner = wallet.publicKey; + const recipientAta = await getAssociatedTokenAddress( + mintPubkey, + recipientOwner + ); + const ataInfo = await conn.getAccountInfo(recipientAta); + if (!ataInfo) { + const createAtaIx = createAssociatedTokenAccountInstruction( + wallet.publicKey, + recipientAta, + recipientOwner, + mintPubkey + ); + const sigAta = await sendTx( + provider, + new Transaction().add(createAtaIx) + ); + console.log("Created ATA:", recipientAta.toBase58(), sigAta); + } else { + console.log("ATA exists:", recipientAta.toBase58()); + } + + // PDA для metadata/master edition нашего нового NFT + const [metadataPda] = PublicKey.findProgramAddressSync( + [ + Buffer.from("metadata"), + METAPLEX_TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mintPubkey.toBuffer(), + ], + METAPLEX_TOKEN_METADATA_PROGRAM_ID + ); + const [masterEditionPda] = PublicKey.findProgramAddressSync( + [ + Buffer.from("metadata"), + METAPLEX_TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mintPubkey.toBuffer(), + Buffer.from("edition"), + ], + METAPLEX_TOKEN_METADATA_PROGRAM_ID + ); + + // PDA коллекции (metadata/master edition) + const [collectionMetadataPda] = PublicKey.findProgramAddressSync( + [ + Buffer.from("metadata"), + METAPLEX_TOKEN_METADATA_PROGRAM_ID.toBuffer(), + COLLECTION_MINT.toBuffer(), + ], + METAPLEX_TOKEN_METADATA_PROGRAM_ID + ); + const [collectionMasterEditionPda] = PublicKey.findProgramAddressSync( + [ + Buffer.from("metadata"), + METAPLEX_TOKEN_METADATA_PROGRAM_ID.toBuffer(), + COLLECTION_MINT.toBuffer(), + Buffer.from("edition"), + ], + METAPLEX_TOKEN_METADATA_PROGRAM_ID + ); + + // 3) add_bonus(investor: Pubkey, amount: u64) — raw-инструкция + // Порядок аккаунтов должен совпасть с #[derive(Accounts)] AddBonusCtx: + // signer(Signer), state_pda(mut), mint_pda(mut), recipient_ata(mut), recipient_owner, + // collection_mint, collection_metadata_pda(mut), collection_master_edition_pda(mut), + // collection_update_authority(Signer), metadata_pda(mut), master_edition_pda(mut), + // token_metadata_program, token_program, associated_token_program, system_program + const investor = recipientOwner; + const amount = 123_000_000n; // u64 + + const addBonusData = Buffer.concat([ + disc8("add_bonus"), + investor.toBuffer(), + u64le(amount), + ]); + + const addBonusIx = new TransactionInstruction({ + programId: PROGRAM_ID, + keys: [ + { pubkey: wallet.publicKey, isSigner: true, isWritable: false }, // signer + { pubkey: statePda, isSigner: false, isWritable: true }, // state_pda + { pubkey: mintPubkey, isSigner: false, isWritable: true }, // mint_pda + { pubkey: recipientAta, isSigner: false, isWritable: true }, // recipient_ata + { pubkey: recipientOwner, isSigner: false, isWritable: false }, // recipient_owner + { pubkey: COLLECTION_MINT, isSigner: false, isWritable: false }, // collection_mint + { pubkey: collectionMetadataPda, isSigner: false, isWritable: true }, // collection_metadata_pda + { pubkey: collectionMasterEditionPda, isSigner: false, isWritable: true }, // collection_master_edition_pda + { pubkey: wallet.publicKey, isSigner: true, isWritable: false }, // collection_update_authority + { pubkey: metadataPda, isSigner: false, isWritable: true }, // metadata_pda + { pubkey: masterEditionPda, isSigner: false, isWritable: true }, // master_edition_pda + { pubkey: METAPLEX_TOKEN_METADATA_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + data: addBonusData, + }); + + const sig = await sendTx(provider, new Transaction().add(addBonusIx)); + console.log( + "add_bonus() tx:", + sig, + `https://explorer.solana.com/tx/${sig}?cluster=devnet` + ); + + // 4) простые проверки + const acc = await getAccount(conn, recipientAta); + console.log("isFrozen (ATA):", acc.isFrozen); + if (!acc.isFrozen) throw new Error("Ожидали заморозку ATA после add_bonus()"); + + const mdInfo = await conn.getAccountInfo(metadataPda); + if (!mdInfo || mdInfo.data.length === 0) + throw new Error("Metadata PDA отсутствует или пуст"); + + console.log( + "Готово: raw-инструкции прошли, NFT создан/верифицирован и ATA заморожен" + ); +})().catch((e) => { + console.error("Ошибка e2e:", e); + process.exit(1); +}); diff --git a/shine/scripts/devnet/quick_devnet_e2e_multi.js b/shine/scripts/devnet/quick_devnet_e2e_multi.js new file mode 100644 index 0000000..37bf6e9 --- /dev/null +++ b/shine/scripts/devnet/quick_devnet_e2e_multi.js @@ -0,0 +1,205 @@ +const anchor = require("@coral-xyz/anchor"); +const { + Connection, + PublicKey, + SystemProgram, + Transaction, + TransactionInstruction, +} = require("@solana/web3.js"); +const { + getAssociatedTokenAddress, + createAssociatedTokenAccountInstruction, + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID, + createMint, + getAccount, +} = require("@solana/spl-token"); +const crypto = require("crypto"); + +// Programs +const MPL = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); + +// utils +const BASE58_RE = /[1-9A-HJ-NP-Za-km-z]{32,}/g; +function mustEnv(name) { + const v = (process.env[name] || "").trim(); + if (!v) throw new Error(`ENV ${name} is required`); + return v; +} +function pickBase58(raw, name) { + const m = (raw || "").toString().match(BASE58_RE); + if (!m) throw new Error(`${name} invalid: "${raw}"`); + return m[0]; +} +function disc8(name) { + const preimage = `global:${name}`; + const h = crypto.createHash("sha256").update(preimage).digest(); + return h.subarray(0, 8); +} +function u64le(n) { + const bn = BigInt(n.toString()); + const buf = Buffer.alloc(8); + buf.writeBigUInt64LE(bn); + return buf; +} +async function sendTx(provider, tx, signers = []) { + const conn = provider.connection; + const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash("confirmed"); + tx.recentBlockhash = blockhash; + tx.feePayer = provider.wallet.publicKey; + for (const s of signers) tx.partialSign(s); + const raw = await provider.wallet.signTransaction(tx); + const sig = await conn.sendRawTransaction(raw.serialize(), { + skipPreflight: false, + preflightCommitment: "confirmed", + maxRetries: 3, + }); + await conn.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, "confirmed"); + return sig; +} + +(async () => { + const count = Number(process.argv[2] || "3"); // сколько NFT сделать + const RPC = mustEnv("ANCHOR_PROVIDER_URL"); + const PROGRAM_ID = new PublicKey(pickBase58(mustEnv("PROGRAM_ID"), "PROGRAM_ID")); + const COLLECTION_MINT = new PublicKey(pickBase58(mustEnv("COLLECTION_MINT"), "COLLECTION_MINT")); + + const provider = anchor.AnchorProvider.env(); + anchor.setProvider(provider); + const conn = provider.connection; + const wallet = provider.wallet; + + console.log("────────────────────────────────────────────────────────"); + console.log("RPC :", RPC); + console.log("Wallet :", wallet.publicKey.toBase58()); + console.log("Program ID :", PROGRAM_ID.toBase58()); + console.log("Collection mint :", COLLECTION_MINT.toBase58()); + console.log("TokenMetadata PID :", MPL.toBase58()); + console.log("ATA Program PID :", ASSOCIATED_TOKEN_PROGRAM_ID.toBase58()); + console.log("Count :", count); + console.log("────────────────────────────────────────────────────────"); + + // ensure init (если уже есть — просто пропустим) + const [statePda] = PublicKey.findProgramAddressSync( + [Buffer.from("shine_investments_state")], + PROGRAM_ID + ); + const initIx = new TransactionInstruction({ + programId: PROGRAM_ID, + keys: [ + { pubkey: wallet.publicKey, isSigner: true, isWritable: true }, // payer + { pubkey: statePda, isSigner: false, isWritable: true }, // state_pda + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + data: Buffer.from([...disc8("init")]), + }); + try { + const sigInit = await sendTx(provider, new Transaction().add(initIx)); + console.log("init() tx:", sigInit, `https://explorer.solana.com/tx/${sigInit}?cluster=devnet`); + } catch (e) { + console.log("init(): возможно уже выполнен ->", e.message); + } + + const minted = []; + + for (let i = 0; i < count; i++) { + // 1) создаём новый mint (NFT) + const mintPubkey = await createMint(conn, wallet.payer, wallet.publicKey, wallet.publicKey, 0); + console.log(`\n[${i + 1}/${count}] NFT mint:`, mintPubkey.toBase58()); + + // 2) создаём ATA при необходимости + const recipientOwner = wallet.publicKey; + const recipientAta = await getAssociatedTokenAddress(mintPubkey, recipientOwner); + const ataInfo = await conn.getAccountInfo(recipientAta); + if (!ataInfo) { + const createAtaIx = createAssociatedTokenAccountInstruction( + wallet.publicKey, recipientAta, recipientOwner, mintPubkey + ); + const sigAta = await sendTx(provider, new Transaction().add(createAtaIx)); + console.log(" ATA created:", recipientAta.toBase58(), sigAta); + } else { + console.log(" ATA exists:", recipientAta.toBase58()); + } + + // PDA для нашего NFT (metadata/master edition) + const [metadataPda] = PublicKey.findProgramAddressSync( + [Buffer.from("metadata"), MPL.toBuffer(), mintPubkey.toBuffer()], + MPL + ); + const [masterEditionPda] = PublicKey.findProgramAddressSync( + [Buffer.from("metadata"), MPL.toBuffer(), mintPubkey.toBuffer(), Buffer.from("edition")], + MPL + ); + + // PDA коллекции + const [collectionMetadataPda] = PublicKey.findProgramAddressSync( + [Buffer.from("metadata"), MPL.toBuffer(), COLLECTION_MINT.toBuffer()], + MPL + ); + const [collectionMasterEditionPda] = PublicKey.findProgramAddressSync( + [Buffer.from("metadata"), MPL.toBuffer(), COLLECTION_MINT.toBuffer(), Buffer.from("edition")], + MPL + ); + + // 3) add_bonus(investor, amount) + const investor = recipientOwner; + // Для наглядности — разные суммы + const amount = BigInt(100_000_000 + i * 10_000_000); // 100M, 110M, 120M... + + const addBonusData = Buffer.concat([ + disc8("add_bonus"), + investor.toBuffer(), + u64le(amount), + ]); + + const addBonusIx = new TransactionInstruction({ + programId: PROGRAM_ID, + keys: [ + { pubkey: wallet.publicKey, isSigner: true, isWritable: false }, // signer + { pubkey: statePda, isSigner: false, isWritable: true }, // state_pda + { pubkey: mintPubkey, isSigner: false, isWritable: true }, // mint_pda + { pubkey: recipientAta, isSigner: false, isWritable: true }, // recipient_ata + { pubkey: recipientOwner, isSigner: false, isWritable: false }, // recipient_owner + { pubkey: COLLECTION_MINT, isSigner: false, isWritable: false }, // collection_mint + { pubkey: collectionMetadataPda, isSigner: false, isWritable: true }, + { pubkey: collectionMasterEditionPda, isSigner: false, isWritable: true }, + { pubkey: wallet.publicKey, isSigner: true, isWritable: false }, // collection_update_authority + { pubkey: metadataPda, isSigner: false, isWritable: true }, + { pubkey: masterEditionPda, isSigner: false, isWritable: true }, + { pubkey: MPL, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID,isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + data: addBonusData, + }); + + const sig = await sendTx(provider, new Transaction().add(addBonusIx)); + console.log(" add_bonus() tx:", sig, `https://explorer.solana.com/tx/${sig}?cluster=devnet`); + + // 4) проверки + const acc = await getAccount(conn, recipientAta); + console.log(" ATA frozen:", acc.isFrozen); + + minted.push({ + mint: mintPubkey.toBase58(), + ata: recipientAta.toBase58(), + addBonusSig: sig, + metadataPda: metadataPda.toBase58(), + }); + } + + console.log("\n==================== SUMMARY ===================="); + console.log("Wallet:", wallet.publicKey.toBase58()); + console.log("Collection:", COLLECTION_MINT.toBase58()); + console.table(minted); + console.log("Открой каждую сигнатуру (add_bonus tx) и mint в Explorer:"); + minted.forEach((m, i) => { + console.log(`[${i + 1}] Mint: https://explorer.solana.com/address/${m.mint}?cluster=devnet`); + console.log(` TX : https://explorer.solana.com/tx/${m.addBonusSig}?cluster=devnet`); + }); + console.log("================================================="); +})().catch((e) => { + console.error("Ошибка:", e); + process.exit(1); +}); diff --git a/shine/tests/shine.ts b/shine/tests/shine.ts new file mode 100644 index 0000000..69b91f3 --- /dev/null +++ b/shine/tests/shine.ts @@ -0,0 +1,16 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import { Shine } from "../target/types/shine"; + +describe("shine", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.AnchorProvider.env()); + + const program = anchor.workspace.shine as Program; + + it("Is initialized!", async () => { + // Add your test here. + const tx = await program.methods.initialize().rpc(); + console.log("Your transaction signature", tx); + }); +}); diff --git a/shine/tsconfig.json b/shine/tsconfig.json new file mode 100644 index 0000000..cd5d2e3 --- /dev/null +++ b/shine/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true + } +} diff --git a/shine/validator.log b/shine/validator.log new file mode 100644 index 0000000..9d2fb12 --- /dev/null +++ b/shine/validator.log @@ -0,0 +1,3 @@ +Ledger location: test-ledger +Log: test-ledger/validator.log +Initializing... diff --git a/shine/yarn.lock b/shine/yarn.lock new file mode 100644 index 0000000..0b6fad0 --- /dev/null +++ b/shine/yarn.lock @@ -0,0 +1,1144 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.25.0": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.1.tgz#9fce313d12c9a77507f264de74626e87fd0dc541" + integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== + +"@coral-xyz/anchor-errors@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz#d635cbac2533973ae6bfb5d3ba1de89ce5aece2d" + integrity sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ== + +"@coral-xyz/anchor@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.1.tgz#0fdeebf45a3cb2e47e8ebbb815ca98542152962c" + integrity sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA== + dependencies: + "@coral-xyz/anchor-errors" "^0.31.1" + "@coral-xyz/borsh" "^0.31.1" + "@noble/hashes" "^1.3.1" + "@solana/web3.js" "^1.69.0" + bn.js "^5.1.2" + bs58 "^4.0.1" + buffer-layout "^1.2.2" + camelcase "^6.3.0" + cross-fetch "^3.1.5" + eventemitter3 "^4.0.7" + pako "^2.0.3" + superstruct "^0.15.4" + toml "^3.0.0" + +"@coral-xyz/borsh@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.31.1.tgz#5328e1e0921b75d7f4a62dd3f61885a938bc7241" + integrity sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw== + dependencies: + bn.js "^5.1.2" + buffer-layout "^1.2.0" + +"@noble/curves@^1.4.2": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.1.tgz#9654a0bc6c13420ae252ddcf975eaf0f58f0a35c" + integrity sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA== + dependencies: + "@noble/hashes" "1.8.0" + +"@noble/hashes@1.8.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== + +"@solana/buffer-layout@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== + dependencies: + buffer "~6.0.3" + +"@solana/codecs-core@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.1.1.tgz#5d09d7f35b0266789d7c1f9306c08051128a6a64" + integrity sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg== + dependencies: + "@solana/errors" "2.1.1" + +"@solana/codecs-numbers@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.1.1.tgz#b7a69024e2397e236bbfb11b75ff4a077236b9d2" + integrity sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ== + dependencies: + "@solana/codecs-core" "2.1.1" + "@solana/errors" "2.1.1" + +"@solana/errors@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@solana/errors/-/errors-2.1.1.tgz#009ebf387b0c014a8fc60a59d65757fef942e4fd" + integrity sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw== + dependencies: + chalk "^5.4.1" + commander "^13.1.0" + +"@solana/web3.js@^1.69.0": + version "1.98.2" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.2.tgz#45167a5cfb64436944bf4dc1e8be8482bd6d4c14" + integrity sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A== + dependencies: + "@babel/runtime" "^7.25.0" + "@noble/curves" "^1.4.2" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + "@solana/codecs-numbers" "^2.1.0" + agentkeepalive "^4.5.0" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.1" + node-fetch "^2.7.0" + rpc-websockets "^9.0.2" + superstruct "^2.0.2" + +"@swc/helpers@^0.5.11": + version "0.5.17" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971" + integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A== + dependencies: + tslib "^2.8.0" + +"@types/bn.js@^5.1.0": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== + dependencies: + "@types/node" "*" + +"@types/chai@^4.3.0": + version "4.3.20" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc" + integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== + +"@types/connect@^3.4.33": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/mocha@^9.0.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + +"@types/node@*": + version "22.15.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.19.tgz#ba9f321675243af0456d607fa82a4865931e0cef" + integrity sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw== + dependencies: + undici-types "~6.21.0" + +"@types/node@^12.12.54": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + +"@types/ws@^7.4.4": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + +"@types/ws@^8.2.2": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== + dependencies: + "@types/node" "*" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +agentkeepalive@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== + dependencies: + humanize-ms "^1.2.1" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" + integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.2.tgz#82c09f9ebbb17107cd72cb7fd39bd1f9d0aaa566" + integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== + +borsh@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== + dependencies: + bn.js "^5.2.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +bs58@^4.0.0, bs58@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +buffer-from@^1.0.0, buffer-from@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-layout@^1.2.0, buffer-layout@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" + integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== + +buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1: + version "4.0.9" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.9.tgz#6e81739ad48a95cad45a279588e13e95e24a800a" + integrity sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw== + dependencies: + node-gyp-build "^4.3.0" + +camelcase@^6.0.0, camelcase@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chai@^4.3.4: + version "4.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" + integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" + pathval "^1.1.1" + type-detect "^4.1.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" + integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== + +check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-13.1.0.tgz#776167db68c78f38dcce1f9b8d7b8b9a488abf46" + integrity sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw== + +commander@^2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cross-fetch@^3.1.5: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.2.0.tgz#34e9192f53bc757d6614304d9e5e6fb4edb782e3" + integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== + dependencies: + node-fetch "^2.7.0" + +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-eql@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7" + integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== + dependencies: + type-detect "^4.0.0" + +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== + dependencies: + es6-promise "^4.0.3" + +escalade@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +eyes@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== + +fast-stable-stringify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.1, get-func-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + +jayson@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.2.0.tgz#b71762393fa40bc9637eaf734ca6f40d3b8c0c93" + integrity sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg== + dependencies: + "@types/connect" "^3.4.33" + "@types/node" "^12.12.54" + "@types/ws" "^7.4.4" + commander "^2.20.3" + delay "^5.0.0" + es6-promisify "^5.0.0" + eyes "^0.1.8" + isomorphic-ws "^4.0.1" + json-stringify-safe "^5.0.1" + stream-json "^1.9.1" + uuid "^8.3.2" + ws "^7.5.10" + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== + dependencies: + get-func-name "^2.0.1" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@^9.0.3: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "4.2.1" + ms "2.1.3" + nanoid "3.3.1" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + +node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-gyp-build@^4.3.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +pako@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prettier@^2.6.2: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +rpc-websockets@^9.0.2: + version "9.1.1" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.1.1.tgz#5764336f3623ee1c5cc8653b7335183e3c0c78bd" + integrity sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA== + dependencies: + "@swc/helpers" "^0.5.11" + "@types/uuid" "^8.3.4" + "@types/ws" "^8.2.2" + buffer "^6.0.3" + eventemitter3 "^5.0.1" + uuid "^8.3.2" + ws "^8.5.0" + optionalDependencies: + bufferutil "^4.0.1" + utf-8-validate "^5.0.2" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +stream-chain@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" + integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== + +stream-json@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.9.1.tgz#e3fec03e984a503718946c170db7d74556c2a187" + integrity sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw== + dependencies: + stream-chain "^2.2.5" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +superstruct@^0.15.4: + version "0.15.5" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" + integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== + +superstruct@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" + integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-mocha@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.1.0.tgz#17a1c055f5f7733fd82447c4420740db87221bc8" + integrity sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" + +ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + +tsconfig-paths@^3.5.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +type-detect@^4.0.0, type-detect@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" + integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== + +typescript@^5.7.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== + +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^7.5.10: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + +ws@^8.5.0: + version "8.18.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.2.tgz#42738b2be57ced85f46154320aabb51ab003705a" + integrity sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/solana-shine-client-lib/.gitignore b/solana-shine-client-lib/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/solana-shine-client-lib/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/solana-shine-client-lib/.idea/.gitignore b/solana-shine-client-lib/.idea/.gitignore new file mode 100644 index 0000000..7bc07ec --- /dev/null +++ b/solana-shine-client-lib/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/solana-shine-client-lib/.idea/gradle.xml b/solana-shine-client-lib/.idea/gradle.xml new file mode 100644 index 0000000..d19c938 --- /dev/null +++ b/solana-shine-client-lib/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/solana-shine-client-lib/.idea/misc.xml b/solana-shine-client-lib/.idea/misc.xml new file mode 100644 index 0000000..fe0b0da --- /dev/null +++ b/solana-shine-client-lib/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/solana-shine-client-lib/.idea/vcs.xml b/solana-shine-client-lib/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/solana-shine-client-lib/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/solana-shine-client-lib/build.gradle b/solana-shine-client-lib/build.gradle new file mode 100644 index 0000000..203cd31 --- /dev/null +++ b/solana-shine-client-lib/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'java' +} + +apply plugin: 'java' + +group = 'com.shine' +version = '1.0.0' + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +tasks.withType(Jar) { + manifest { + attributes( + 'Implementation-Title': 'solana-shine-lib', // или solana-shine-client-lib + 'Implementation-Version': version + ) + } +} + +repositories { + mavenCentral() + flatDir { + dirs 'libs' + } +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.10.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + + implementation project(':solana-shine-lib') + implementation 'com.google.code.gson:gson:2.10.1' + // implementation "com.mmorrell:solanaj:1.15.1" + +} + +test { + useJUnitPlatform() +} + + + diff --git a/solana-shine-client-lib/gradle/wrapper/gradle-wrapper.jar b/solana-shine-client-lib/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196 GIT binary patch literal 60756 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/solana-shine-client-lib/gradlew.bat b/solana-shine-client-lib/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/solana-shine-client-lib/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/solana-shine-client-lib/libs/tmp/solanaj-1.20.4.jar b/solana-shine-client-lib/libs/tmp/solanaj-1.20.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..a385a6890e926991261e99eee0b9381873c6d002 GIT binary patch literal 222190 zcmbq(W02%;vToZwZQHhO+qP|U+BT+bo71*!+qQXU&z^Jd?mu?-e7F@+5fxSWE!>AA^#zR_%AZWsE%)iKR^HN z{pZ{NM`OQr@U| zBSS4UsdVEAqX;oVAu~OpM8CuYR^~uCIUzCoC^@|QnK>HRIQ<70{(piQ*czGJIsOCsuUh@hK!1BWf7AVcv~sjJ`VR=qe}i!L zus8WfIsbYR!GFXV+1Z*}{G*Zn3P=4HaA!L!6WjkF>c7IcI9pi%Co!@A#W{b+7+Tmf zG5&|si2fI(k)wybv)%s(12+R}YZK@Hz<}(3k>I}>SebbI2PR1Wf{ELIdSW>L8enbV zbmx_SjJ4b zxN5f5aoc|O**?zkdh*Q)wy_ok6m9{D;>hV)&b3QKhzq5DJ76cGLNQjag0a}x`VoX>|jaVT)C7+LP zEFilaIRTY%3PEOBEm@JB5975UmtC6!2|I3TH4ym?f(^wsoE_&lFQc(ojbE-nL^wcR ziB#K)F2X`XGgnn^x`zJ*zHA=M(WWbka|XK5UO6qJel!tQteGxk2-MbRmT&ba*av2f zJWIY$X^mK$oJZ^|#^MsFU3;V$gMq=^h%rC2i0hPTc#Ng%ER~g>Sc}7@@p*|jgRPqtedG>c0H_ie z4}9tMPIUQzW|2A*ut}(C(r6ItFSCW4WBiH$FHMnB1xq!R1V@$G?fpCk_$Tv(fIAHN!HrV*0_ki|HKB+OU%7(1H#F4$uU_#|m| z@Qk&w(YDDUT=N(r@TD<$#YKhx2&x%jS@cvy3hMY<1g@rA)q&Pnc1FcYhkpJTbnh+b&#GtvSp&(HQK=8CO#TgK52za^?uAmN} zyjaSnC#k;$U|ifl6ogPn_(H;G5^Oxc=$xX2$YNWfL`u&bzUQOsXca(MwtY&PlW`$~ z)TgkVDab-F&tQ(|UX}ERD~8-K6FG+~W!XG&%Mw#;(K9hOv|Ct<(vXh(Q@)wE_f0@< z$kX}{8KeAKGVRhFory?U`{+u1p<*dDnyRPcF?ZZ-IrNBfON#tOgr_K1f-&JW`BluY zhhHIC*?A?&Em(BOw}cpULsB5t>O+JyPmuGR)uljX@r)LY7C1$EdkegejrMDm=5x zh5|#sy-l;v<4$)Ot-NMn1OI3XT;6@LRTF+1!kUyVVZKC;#Q|h#v>-IvVtDEeVq*7} zNs(n~8tF#AaSxvdcKHEVd?B6G_RA)8upq?$#8MVbjZx8|w{a+3rW8GLjiqSC)p9JK zm|jk@b`&XNdT&O0l)!lT43)CTe&fE7Aop<$g2Un{l(UE|T&jOAY<|YAU`zR6XIC*a zhOxw}DXFNgS4_V*0N9~}eJvZnYJ`8E#(B}KvBma$pmCjEIyC3j`bY+sPA)2GsZMd{ zoKp`j+0{3EeoS}Lm0JCsdlwXAL)maQ=}P)h8UcmI&hI;~;}f8LSe2CK()@MnlMn)= zkE)>U-Dkot{QcM$B-s0oU$ztJ$4%lkp|Wq$-|PFg1d3)23(WtiQiF-xXV^$ z80NWiWIcq9IYfL*wdVUPN0VJLq;j6*x1&yCM4O1=&_hfgi7mt}o5Q->=xo*4+h>7X zr>zOU1ezMk!@^$BE+dmg%GB!nRzxXi3Iah<7`$$a?N}Z$ND_=ZHXsDK~A%{V<`^lNv_yke&F^55|7g3 zz@O$!s!e>)irxCyS!ogG%eHSt{#u$&uPr6$M=4LVxK+ei9V_q_~C}q zC0KHh*`tUct_bEV$E8&rtg&9?E>Ez&85_SfnBE|84~$|D^pC(}@O1`HC03XeE=GWQ zC*7P$TqDvVHQ^u^$If;_^^MLw@9(#+Ffl**<;pn@$ldCDW9H;hjh_)Y!|pX4SYo(6 z`U+O(o==Ulv$Dos30&RDTdfC%na*sV?(4pe^peCZBEss!b*74vk6j|~cW&gxP^(Yn zWmO9SYDZ7+-WxY!VzpQu7Aggcoo3Ydf5@hO5MJVU)nb;{Q7Q6BBge$u78pORe21T* zIVqb-glbfcqs-(H3{~4eHduT7kk^%!M>Wb+ky51_E~iyPSZs}exXVmMvoE9Cy+iLh zU>$KG9`#B<$i?mQz$HR+qS-s1mZd%293CY+*Wrw4M-SDGN*@o4ZQ>3phsoxSZ5X6C z0;OkZMc}VVrk&tzt2g^eJ)jivIE{J&uI&@vY1aPs+-h(Mu~`d1vZTnRQDJ7^^~CBs z+JkFd)fv~jA-@ik-TIE04Sbe>mSo@tMmM>>)|X+MU@fcUkXbS$Ip${jadh&SKwtrtP@(Zk2OFZW_J{@Db~H}T~^G$jbwzd-ATNG=;sNZ zyp;tyUy8ZC=Sm52uE4ts;+^peS&Sy|oylFsVd3g2EZzUw{jA#;(2jhmyF{6fxQ^xe zYYL5^y5xn!H<&LFcG_|89*y!$w7e4FOSH{znD5q(`3vr!>$qvv&65YvKfUOm zYLoJRspF(fJe;Ke6s~`-=dx5^)sWPXzp^2vA&?*x_!rvpNy1qqn`i}S3e~FwZ0ho6 zCdC+uf%~O7nR@4Zwx4y{KUegu(8}Cpzx}hnWSX8Qjfr5GOOA~_uDiUty|z2IeXc(r zr|)tAWcP;gS$oKO=?XxrV0JaSdXO-e@53YK8zh%Z&2bc67I_DEu)<79?4|2C0yEVvq>3zLCKG@|Hi2gwOB7T> zy&nu4f_O2sYLgA#-_DS$ZKBqT%a1Ww5j<%us+lqJ4z@^)xLoNQZwwWPGIUTx%*>cb zc&sWyve6Z$lR`&bFZygDy^J4>=!DEga3Rcf8SbI_2l(6SBuATwt==N4o8hmnQyBco zQG9+{kp!35d5A1f2+bp-;RA)VM18h|HkNrx#*eXc?qr>Yc#`oj#WOlr2zwRsBeIk4 z#zhHiNMStPP2*3ZACXU^h9Lr<_dzb<8my?#W3b9}kpn^Q(Z@iY;TfG^-E5gN6OsD} ziXsZZ;M@z>B{Aq7kp6~E%rgsC5y?g#DKX9*`h@Wvr@vJBQC>b9mHQGFg^Y`DS+>-Y zzKk+&(Lzz@EIJfuNKvYZRBU-~A%n2zM0gX5{!|_RfZ176oSz24;;AX`7-bO3hH@U} zj*v>sO}&p0#fF^QeBWHjA>Ty&tSR1YOa5We8hZmgIQRn09HqUv_qri~&daffV>edEl!kXgrPa)9hmT-N58 z$IMstD^=tbozQ}4yb0z~X<}TkTSva^_=#m%SQtKgyh`W$O+6nY#8uZ%{OZe&$dR5* zwteJmAv}BfFoY$VV9k2kER$&BNY!XwSxbhxQheO7E+HK$8&yVix6sXs&4i{eyY3%7YBdQfGc+|1C-BjN-QZPK}UMR=-q2$vNY8kYLT;$yYUT;SVQg8GHb6Z|)nOViB_m>i)Mac$`S%}%` zOunvdPEF3I4xYp6h|G~j^)d6{nH<)TcG<57cJ5_*WS;kLRGrlGby2mN;+Ep*ie|zW zAK8*frXq)NMQX_Hxz&}0Ct`28*se#F(*dXC)8qwNH;NN11Uqd{aGu?X?80H9PK5IN zk`s=JfrfP79MVyUP1mTe{yLJ{6&vwHDf4%nUaXiWl($QKSbPA!H3&8cS*F#dUgr9T zX^`zPcQtXj6T9$j;TKZRA;WHh7QU`1n;x2r2cvuh4&fD?lY$n|JK5#7C~8rr5hPdt zC20B41Orqj6FVbjwDzl*#8j=7VR$W3X?MSAoXB?m4~qg%0^Czpae0)+Vfe?8@-?PX;!&135zL-ormGr1<%2&{*4eo+DlSYQ zpNsapcV1*NqrSBtFHCK?I-6YenGP$CIun{`%acIcr`o9~R66N`0{6Hb8b-Vazzz7^ zv2+p{%CUSxYly^2u)DxUzmYz85u@AkXCurZ&8!qeO0V#J8xg3Q zXPsnua!PLB%{z&ZiJfP`yZm!8ZX2Fs#6v@oRm!?4P29*EvJG>7w}8zlB0&dq%G*TD z%g*#HnPh^0^#q$}qr$j51AlT4-B87B+q>(nzv7M=@QKu?me+=Acb^=*l5|LaGt9k2 z8Q1Kvbeu+Q^>H5C}HY2wG7(hZ0~|Ud_w+B08j-603iKe za)*qGv%%l6I*GZ!$VfdI;SY0Nx~b(>6oMpBocyQ<)9j9QTu7U-$QD{>Lj8xdG*Hbi%MMAvRfX z`=j#`+9y#|yb(%SkuUTzkIHFoefA+k#_7h4K2%+bUVaAOv)wVkk$RA`{5`dVkwzTK zgl77{S`b3aHUx2l$J&_L#)SOPHhAX*oGpVhxVO-_NFL~Z;-Z8sFpp-6688alYwJ7) z5TSk8pLiz@c5bWUFk4bSr0AMHWdrZ0>l8H`;3*8xIp`8t@(r&mkCgfd_qk0)xj%4Ia+MTg8?ionG#lA~Bma~a z1yvZTHAgL7`=ZOAB+H^r^;<5as@ldjl~Y-7Be%`pK>uueO>KAs97_0%(JNA6L`9;K!t|(j7G>^}K4+LdCInMx zo1*i?Wy^(ECJd@bmpDxJxlGV&vpt?Ea!Ixs)FD0(?vn{CwZvFLgq(U;DVILETv*Dr zg<64qhXiN#%3(vq4|3ZU*XbL~;)C~bX*OTTOz)TQ3W-+WyG3ZatoI?NU{q(_7%8Y$ z_dmuevYk#YZ!98zG3#Meb9N|(@1_i;!Z^in)_p3ejRRY>2Y9*ac=+Cr(5C$~IKp93 z$`126m73RCR!OGVv^BCoZg0^oiG-p{V9UQZQpc5F=$DQC7ognIsqjtmMP)M#` zIn7)M{%tmuXi#2`y|s3n&3tdqP?nKEPOZk*53S7ZME;;^-(g$|Me{N%$f!qg!K98{ zzxrF6QLi+)^ksE%t4wcnxG@p_Lk?avnnZ9%aoQfxkol4zeSwLALP#xcA_=d{*iB{F zX&{ApkIt|Bx@%X^l#-&z=koRmOMn>D7pw+d)op~eb0k=Ec^~WIO3;~Wg18ONRFHL3 zpHHT+HcJF_yGVhB*1NxUVVQdK`Aj`%4%o=nL5wQa`8%`b2PjySuG8;X#4kmavVB>u zq2gnbtE^@bY4*2qX%f_)H5|L(OiuJ+x5HA?Triwza3&(9UbJK+h-qeib`a( zYTBB9Rt)m>L?lA{negJ{#O!ycL5G4rbgXp#)W|muU-%&) z7TIldmkL3=sFTT&$c;(j7rjXTijmAXs5qE`N55L4{{`yLF_v~sDD8G!2H)EO+G*q- zU`I$uO_=cI;y+?Y9bcjjov7A#5GC=2qy~1MI(=Z4|KajBdQMdF9r*X)#GET9B z#S}ceQeoQMXA!Fj?WMF1OEM#Y6 zZ((g>EMe>9?C4_TY++~n_r&3&C}TIz5ATyv_-Zec!76V~9^4F=fV^A2r@AwPFI?Ct z0(96{gynU}&c0>t7P!ObAOJ+*FaozDMqr92g|9rgG_E?z4XRnpy`PAmBne_BXoVZ8Dkp0uL7DGc9GxCY8jm5g8ilmUX}E$z zEya5)FH!|GJxu8x@)qQ`19-c)W5|qGDpHudT&JvQB9r)47|-GO%So{3?_YwL~?mu|>e>&#K|LUF*4{;7IY^4~co zf{%*TO}UcMRGxi2=|;)bvT3SFzYXx-#HQFByOZB-&d*)E8ptVU+9Po4-N-%n413OT zeSyz?#SSC)FF0+E>aP?G2cEwX?2h(CHry(~-A}x+bkx#YKMA0^0sq-!GHEqmV1NJsEdF>5{r~1M|Lr;A zCI-ePj{oB;epW~Ve|%;9T6c}uro5?1Gdf*+5b3)LN}{qju6S;U{|0V#gXT1NTxW9~ z>8=WyIv@=R0pT6_fjn~^SYjUcVNQ!oN4O7b zHk4TWoD<#6f)rT6EcRK-l8klkggo@#YU>NSmtqUr7V!>c3ZbFC&18A{%0gvU(BLNh z&2c)(M#_GWLoVTDdD_ZS<))wdb%1&Ju>2YBZ(W=mzZ0D2ZJ0LY-5|p(`Y>d;g}C=R zdUHdtegUJ$ZPrkjQ`r-!kmzi*FkfygXpSAD9KuE26MMgrqLNP$`l{oR8~38CyPH_^ zs1iY)kSi_PS7~wr2?Lqn%T`1hiq}kItjTAakUbG}DY1?xX9}mhJK<}8f^D?;vyk|) zyx!X1<-CX4AV1@9a>U|w1uV)4Hi{&UEd(((24Focs1AzkBdMzp-&VDEnui=U^jd=w z^CRn|Tw^;L2Ebh_`>p8Du^dwzq7ztAY?`}>DSnTt#*=CZ{ybPxAb6#GqA*l+K zgkqnOsVl^_hkHJiUp|$06deB=iG?|*k_=Qx&t*h6foKNH`Cb|&9a!^ggk3;d0_K*! zK}Zi0**md=F5~-W&tff=QQZDB>K6Y`gRB4csK5JCvO1(U@*>7}_oj@gn`<0^tuX>K z;D9v{m_Q&YHYq_*3b8O^IAF50Ybbr~Dr|d0l71E1WAT!uN~MaFRUN8Ul`)5*g4e2M z)3brr`r3PalUtGbM;BY-1*tXA=Vv{WUDtExb(gNL_wk4VfE0*w%Z}>Kth~SA&wQFU z*G|Ub;dZKJXB!5>6#iX9CReBe?DS@gvVS_LdD{TE|Rv-^EkH{hz*>Wyn8Cp(7PZHCKT4u z*pNn-Mu@0Sm})Re(uYP?O)OM@nZdJhWSQ4vH4@;sNCG(%6tGfP(6SuB-Hdl`p{Rzp_>I`xeFr_|C z<_xP778kpR==}zNxj}El0Rx-CAJ8VD_vFD2hf5Y&W-xAF4od=tMO~Z+t_&E#ns!@i zRA%Ak&f12UNj)oQ0NM$3KkTCElV7qNg)y56R7m(Unb)(BSzSEw-7|FTCsAbS z{^hgf%1>U&vMNzLn_mb-D$_vFEv(`}6)YXG2n*CeXz9;ZEvU<@Cbq4%r^d_maXx!s zuxw*U3IXfBrZ?cs8w2`qff^lJ%o}48`$UMW=>hAYQ<&R?l&<@MP*)2#1RE^MC;O)P z_0`jiXLA{>4sl+O=qB~H3be8~t~=tyce^$%TKzng!P}BIG1e#(JG!vXyS@=Ww;Bh7 zJ%l#ZnI&)iLt-7#JtvhbR&m%8c*hoFE!@MZaKlQxmN<)o++3)#jDb`35Mc3+jmpz3 z<Gw9Wjr}ys*xGJ{NGKQvsov5Jigz-#VD^I1!kk%Fqd>?K)k}I$W99Br0bhyS4QdK2s;?4%9WIp*?0%~nf!v&-VpP{>iT%>tD0 zFDP#w7F4NNt@8)%GEGX3OCCU1&B=jc&dI%z12@`$9T4-OJXLljhXdf)a*rBqgBB9;Z8lEZip_xlI$3}ZAVxau{M`AySfS^GtpgDP;MK_mQd zHpYlI&rrhC0Hw$cZ7KT}TD~Tu{a61{Y4fIsktNbjHOT_|>pLasN_1L7BUnQr73#(q zu6U&w&~n)p@XUN(B&WV!*Sd@j8Mc5#6oQ{mv%td?b=TTI3-O|x z9A(r1UyCyez2~!HZn{X8w~O%}u{Ehc3Nom9x`p&o`(&tgChh{^4}s-5fAlTGC8vlq zW^Tk%$VmWg7abeBpLpQ%P=ybABOZEt$Kt2U0BsM$ozUC}eT)#`5s6YiZQKFNQ!%m= z1!8ny^IL%XOgXm0?QOt}L9!O@(N8($b$*O0e9+=A(iLW_20LmKzoM)&{wNQkJ%X10QPpRl89WyyeO}TsReac*l8cGZ5;UOw0z?X< zuP}TN373DQk@8M|a`x>HT$MNjNPUeTSbZYa!W~#V1Qp(3{6^5o++M*QV^aZrv7dyp z7~I>}uTEDB9(!A^w8J4?r5XUWDveux2i7s|Ug2{^$&w4!;l)690$qBDf=HB$E4m;e zCdsst*}K%f=2~XBy;A`!UW>h6zL*=x8R_;O4}%DsP>i=8Xc>pym8je3GpPXCvGsa3 zT&*u4--Ls71F{HXdsTUNfn^PiDqaTB-d1bA)KQQ%A1TS|1_mAL3dWtKBFWDY#8uu2 za}Zq9x1?yIsVEhwrZ_%l={JM+Al1v4*(dKa$bE83{1eakq#q7O=vne) z%LjrJD={-#>~N^y9qby~6Cs zV6}@K5hXIZU{RzNgEWF*?626MmS0!0mn)<&g~D*u4lJ;fY=-SEp%JfvD-^iHEPIgJ zR53fAx7@bybOx#JC~V=&4opR(G_-uSE-3q~Y819^lY=#3Nc-x zhY}-c}?l|2+IVW@p?Y>jYWO#Ir9=B8) zLn*BwzA_Km>a;QYY{Jvg$$K;(Df+mLVQjZteN^y+`Pkhhn}P_4W^p{aq`3DY2w!1* zy;QWM6(4D;ydAp-U6Z?X1HHw!YUMC?b6b})q@ZA<1Q9^p0g{|AY;P)*#x5`k>0d}Y zP{m_(JLrOeC;YqO$h>MUdmO%(DSpDQ?B8&C59mO{JDf3tAY36Vg*)4$RUS}U-zR;p zY~g;>=)uwFd}z%qzhu3n$DPNVMkqd_QM7+i(7iFSU)-)VwFW@Df=$bJ`no#Xbj5yn z@x`wPt||jHSPT8oqGPG{Q>;O^6#CBBgWLP@{&^r&T;J2_9HK+`ymt|S!O>)G3#PXg z7=ZEa)>@X`$?A{BN$U5B-*tOoPZ~dc`U<~z9I6l?MxVH3;%s89F$Ost%)v*b%UzFNvifuWF~+~FVOnd+z2T` zHh9g2ctqybz6JWv_i%#vIR-NikEi$Uo>x)F3R3`?XSrr^QZ%~EVy*ZU9&dpkRd7^lPEed8IRZs9h&$$7Uv(*q zz8%WrgzroUDw!Ye4fw7=@Va^^lyI!C)9h-?>1udle?F%hV5`88@Mq!Aq+n*opgno% zpi4+UeZNcCA|ymcwCd{+Jcv=v&I}<`4&dToSoI(`Nw|ykc`Yva2?U{a1IuG12Nt$B_x@zWZoYR42H$#WTQ%mA>c;}h=Ka5+@>lG_%tm5NL zM7>y1YEq9GyUXfa56IZg$hyUO!mono*BK%BD)5=@`B(I4;8`) z{N3VB>hF5kizweeE*Qrdtq`U2(P0upCH-AkYA9#T`3;wP62JtB%Z3cx{C}F5GI2@u ztchaf*w{obEr}^cupv*IOa~TqjpUL?XRxWUp|&~V9PDmX4|AyJj=Aqao9ODepY;i~@YYEq@diJL$y{o_FcZ`g z(6;&led(QVvccpQ9v>jN%*?pQHH=^|@EcJ`FxNFXfS$}JX~|MO^ig}EvBZ9-qE#N^ zG8%IW+)(w9qp#&bO`ud4Q!m&QHp4!PzNuRuf-UHqxmm1ZqjDE)L);B4`a{1$TY@tl zIYf)OagVgCaMwR|@R1}_zD}jL$Z^dPQ3Q_@8keCY$|6d5Hsp?y*da3F5_4@fZzsSa zYQ2hE3g6J9*vdVIst3tdQuMam^Mr1Ql;AW}5Spkc9YKIHfMU077sGtByUK_2XHs}(X0 z?j6QB2pFhq`z*j^^wv@5Dg~wnl0=6|Z(U_KO(D@ZR1A8aG{nBXA#yPK(!M$RAOp}Q zC+I?}8TEF9eb)Lxcd)|(L3q*@+@Do_vvEjK)s$H=o8Z#(QW&QfszUs_CWp@)PhHNv zI4mmgooyUA`QuF7PNH79OUX*0DQuI{T@q{`Eg$t~Z1ozOr`OA!0!pbN1uL{oL)1m5ZbQO)g8t(moUrYlUQPl5ShUXc;) zC6x@2iCH4CD&E4qB=eG7(9LGi6HzC+tkbN^F4{bk+K(e8+4p}&#ncgA_TA)j;K{dtxA*QA1rBA$ka1`Q%G4_H{qeYhv=@5t< zIlF(QTR0|$;nCMA3gwE@)~BUp4aMn|bxqqaJo=4&b?=r4wWPI$OjA?y=OSsbBe!~0 z2s^Vu2l_5t6(^;d>iuiMfrywg>wLz$+g)YZcgt0d2+BxvPB$NS5UAeHJ~b;VX@dxu zHBsB6(*h5R#E1!q9aU?rVCy%UJ|ko45ohC8?C}s(&a6&0sxe^h=MOqeSeiwA9AI zP)qL&o`Y{7xz)nGKu5M$CPRxR-VY7As2bUIwLeg%Xn0I(Vuq&q(tg>vp6ShMeSS(j zKWDw_G$z^@Nr?Kr!-$MA#OxuyAxI%fcB2nXCn_-GJgb;INl-UMZy($2bF`Lad$G(3$TJm9N*9fm8B<-TGa$E+oeN(J#) z9@#`s(AzFN+P*qmHCv?39i50=bFNwDH;dH`cD&lH8SARsVR=ONox8oS0;{MVI#tVM zk^>us5Nynjll)E8$CHP0>I{R2r$Cf>iA`ywz7W zJ`+kq%ITaqTWyuO=w-CCX%N|yE+ptj$V%$nA;&g_VXpEie^tlEvrOBCNoOO8ouR7C z(t*^Q!=7kbOf;|C{16kv!M7Ntut(Ocp5$TTFvHE#MjsBM7QyPGcc_;L5Vfc-N`vE1 z3^5M1AqG3KULZ(b6yAPVx&qfV^WaSDBrp~|e0yC4wp@M>n_O&!F{BpHW?#b)-@?*v zNImEWyTV3$U8J`I&wh|<9?tQhHVgnu5r9FFXOGr5*g0QFyXqX9({v~Id+}U7_-^r= z*8IF%&>$f(tZm^7ilFgW)~=uGq4aCSuu^C~Qx&7lFDycXrqqR0Qs{Hc;8YP;)ji9% zu(S<9<9PepX~w+5b3~awWe_LKSi^NDtm$mY`UQ%a4iq9LhcuYT6z&JeYo2mDM=>FZ zJG-TD@2;O&rQdhLU`t&?1sfAC#Ve@hdVcdHXGwgQITgAUN2pD%%d& zK8E(#M<8!Xw~)p;$W67~zd8MYg69c|_9sS;;6+5O1cw#(UJ1+7g&Yhn18?Ui*1S9` z;27+#xn#(QI_|NJgEynSZUJ(7bl4}-0zZ(a<6u0gn9x>4Pl+o|P)YY)6Bd8ch$BSE zZvAr8N3-kvotJ?&tW&GOZ4|Xn%L}J?O+OrK7z<*pe`pjw4 zv_{8>Mg)4S5u020I*A!q_^!Yd>}ZJ|92N$M`*G~fk9srsV;D^Rdgk}pD1qi5k**=7 zRtioz3phvH$YNEMr39l2AU+9cj$Myw2q-LL7mrkyN!nfb7#PXeuP81weP*=@H*JVF z5PiN*d|3A*h2QH&H$$PFh<1Biz9hSNl|%{>Rgv@_K9}?Aeo$~vjzll!l(?QWb6UDy zE$_s*wEb7?Yz6&5bHk7pmyq5^>StT^5-G9Nu_eMDBU4^12rGC8kCLs+*n7u511G*u z5#TGWc!dK()~=!G{r!lskIn`NT*Gc@k%vj8eb4A-VSZRQs9bF$3rmK@%~K=Fv(!G5 zN{CHM7#vtauNXl|2q^F0B0ZnR@4N-yfWGL=c`nL`J*pAX1`9b^n_;*avtg9CM0fa@ zbL)y{!!M9ID&EgZU)_mA(>G45XUMt^egs@K0ebh}sV@cAxh9#h3@VhjWFMe@LX&=f z89)hM*uO;l>4Sp*450}AUHz-%;pA%Y-xH_ccp0gFe)y1W8>_^j(k9I&U#|)%Fi<&_ zyd}xr+ywDFveluY;vwM#<&$YdI8abOe?G}f84(`j&Hjmt_WRq~`>)$OupM|TOhs|3 zkrQ;G6oT!;*o~W(Z3fyko!tSLRp4c}eWDO&kA^aS6Lr|WnA_TCePKY8yXsw#JbGF$ zn`xIRVZGp?TASwrFE2Q;PY})gLcE`Fy)N0VF zCjm1mtFQ1dsx=BktLYMBM+cD(SPFSN`T3M4GoGc4{_4p%YaIg1kFoH9_)U3w@qa%W}R!mKiGuVLTTh`mQ& zv=;=J4=whrq!x=6!+DOzn@5mbDpsl=N<`HwEKCK>WXpUVRBh@ki!8FG-m&hno z<&cIPOb;p*SY?Ds2fhWwjkSt!nJ0t_4!1b4an4ng()OgajT1Ss`UjkcX$DDG zeuyMtaZh#9TSj+nB{^);PV-$KK9jZVDAZslG5o0u_WG^Ju#8rRV$H55tR6@Yz}o0$C=u2S;<+Eb9LZwT~YK4jR5wrH%w9 zJR9yX*T4B}dhoOEikMFIICmEd>7|0f+OOL47NAukscw1XPX?VMY8*Yy%}$kd8Z%jX zyJ^B%ER$U|>u!}=(NeLVmcZwkxpX8Kkt*)KXY`X$F%>UVQs1Lb2?vy@uA83+!s^P- zV;qVEL$Su}ij(v%q7TCrXO}#h%?_Z(0ku?CQ(P#co+ZgmjTYv1lawnxK?mD-39xxa z_>I~T5oY-S{gLoXkY_YvC7jUJ$je<0^vUSADn1_Z9YOZ0-~DPd$V&DnHjBE8?CecZD-BCw3ofGV_Ea@mu{6 zh{kGi0?mRMuOMg*yqRxgZHU=J!#ze~&csBl5#hp{&bL9EP6_ECMOTLGP4VJLKT^h_@~zjma4 zqo8i>S)$m|RY+G&IxtV)@-8qhd_sG%3@~SQPh%@vl`h-2(D%{>g`|0zw}?dv5>U^i z*7OP%i!h-mj=xe2P7~@PoLK7iki9=|TG(=Pa#WwRGx-`11MzMnM1iD5SP_9r9r534 zP4wBa+|A!C#$bxvFLO1D)8|vXV?BRkK%(B++Xx>X!IFIX%iRE~GQ7w_3nXMpq$G#) zv`8nEh_{N=TPt!!AMfCgmnelV2;h3g>qV#W{-XvMO(y@mh^wm9>p`FOOi`#|9TOmy*9DeO(klbs>KXViJA-rJ(Cl zwt(^n0RVV|1^}S>cLm)))B%Dn7S{iFov2FHMhQy=*_W1pItVnON?yuBhQa1u5wo&M zrFm|OK6#ZLTLy{7%Ege+>B{sM)OYZddEI4{uiJ-A%&{$MJu!0Feri_xarS-Y zJ@;{T=le2W%@+VY990OeF!94!Sbi))*LcotNAINNmw|_xl1@k$$L7MO7fif!F>ziF zfyL^g_r5C8wfe!R+kLr-)vHWK#t$`}O-7?Qc#Ix=V@M&!5QaYc&&FI4IX24lN&1uK zD44|Hc_6d*c>R_?=ex{1*wnPDwpwV~)>o3qOw${(hyEsx8bj~*2nm{Ac5)%wIj4tN zUwh8BwK`8}l|_JIIu&fEZXl4FZE|Vg%s6#M)qsheD`A9wMf$*S zZV{e@1m%zra@$}9MYjClVoYce>^v+lXDJ<}DnUbfIQB28S&cD!^LizbJX*AHgTE#u z*)5NH?(<7FeshFsWWDop}i7PgCS$JZQ=*OP3hLN@+{2bSPPxm51cOV51+* zWlvv!&_lkWI+&zS=PgzP$u?_IU#KWH#iL5Zzsru&a?goa$~yGy_qm$xL4w4ask1hy z#tczC9174W>XUJM1t*|zI33mr31=&u0nvr|eVg~IgQC|^bqMq>1~7AKp0X!!Ivt zuzqDVitx`_4Z@IyEJGKCUzK=(k-v=;PQ?~|w%Fxgd^4`K)s(Lg9{kw}HXf}7*KJB> zX|&lYk7Kc-X!pb}o)nZg0Wl1jlX~H2h&jM3P8%3>*(h7M z8H?h{yTWH_-l|#zQ}%LiPH9UTnCHM*LZFx-xfsh!abBHIkC?3F#?jn6wRe@_w+Udz zi{Uo)c|M-pTDtH{HNK(Ps6vhkp;DTTSz=mIw~@(BPr7Ybm9nujPB(P+LKGHsWG3Fr zB|_~-cVY@S5TDSiv%|B4IQtJ1bxsv+IQOBNszYhD(xGpmg)4Y9#XgUDJhg;_RQb8v z;Zl5HExho6y9u74S3T`>vilDN-cLjV_E5Z~?HrlFppofnPmMv`&yh*)C^$&IxRRsIH`)CLk2%T;(Pn0diQw82mXaS}KwK|Kyj@w9b5 z#kQ~b2iLlDw*?IDBP}pelI<+bk?bqDK4g@K{`Z{uB5@&|RlMaIIu4O>ITWV$SDm-OJv&vShmSLZ8 zgf6cE!dWY2=8naKg_WCclN#5HMX5BAW?yeqCCg*RZ!}SozDk%`)6E6z**@;8U0z!_ zbT|4a`09fnz`8dnEjIurtnuDZ$b{6*M{AHf;h5)&#T2I%MHB9s!)w)q)a4#!3w-~@C&H{A zCfoDSZTy|1yTwtiEfQ+{2E}rKi~y}MzMN4 zl46*cX1gXr(v=1h46>t*uk3J4Q^R=fX@!ja?rX_K%z9 zpRY$N&OpM?d;vfK&_YzbCB_z6N76i|4$f?@y!_Q@xPVr{jrq(w*dC8572Z>lWnZ($$=zD%0yuvQ~wm)3D$*9&O6z^`#PNSNHBp15B+;N2E5VVV3F-z(r=t43fjx z>X}J=UV4g#X&MzFRxZTU%t7PI`83p$J#m3hAEN1nncZmGU3+AVeLCbpk@YRMm=8)qNA~6C=g4JPsxY}bdmi#trItGhq6|=VwZLm__W+ZdW z%tY__>NiCKkZ4d^JwSck))Je%N;8ppX5!P)Im6@1RC0T;!XFif5!mfAcG`RC%7S!7 zqN|z8v4cNn^6q!R@pxKY^*pJ0n?wtaf^W3#D42e9ZY4f%OcXwlEp7p0XTJ6Ek?lI^me zxYlsRy3ggjc!fk$rOl!4m~Qm9V7Bv2FzYRa-2L$`M@1AP_<>sTaO@#oQ)HrvTz#W#tudfmcqRqo( zgC?vLQqZ!MIAF(94sK_7dYXv4I1F-K5G*QYZEAJcRWp_qv?p1x#4%YE9Ed2k{xH?gfQsX>9#R`-P-D{TLX^KyyYnoz98aNk87#WRla#CBAzDpo5j zxemJ1jH8`)7P_-g{&!`x(qwDMj3|bxKbLV#*1e`cen~TJ4}<6)kljp%9V7PAoEGNQ z>?+HIFG)BeuRKXs0BM|}DH z?W;YxNKRsmTW;{X`^+ein=wEQg^q8t@68_<%2y@|wD0@ZPS9Jx*wyC>{i5ZZUj*dR ze=cepH=Yf34ZxHe;Snl?y*D*xS@J}?7zYrbE z@&p(l900?DW59Vla=#An8FECvKhexu^xm`ut$$m6D~e%Z>_?<8*bK~k&@phbgv@P{*0{F>p zEQau0L2Z)bzb*$yBFtmG1 zOR5WK2-y2K(^px>J1#Tp-Mh&`ndFLGmi=xm`<>?Fzb@0N4rY;m-bbSfw|on2M#wRn z7eLBseBbaCt8SA$eP!%TD9t2rrsyqs@{ZQo61F4_dkx)?2SI zul%nukKE!ykUvQ0Z9TU$>ZbV2ufC6pE6&$5a=&*JfAgDi25iLXTr9{u#qH)Z+J5LG z=)ZaC?09!t727Q^SuHvdkqP9$kr*~ZkH5fxXC6Zt(hz5n*lG{}-G5*AG?(g(hzncV zGdqkbA1GvFgxY!on`AMEo^oT!k+%T1DnfGdR({uVx|)N(wT zK?2F{QT&~w&F8_@ntAvbHGDS&%LCX0_R8Ha)-@M=_3<=+Acyr<1IA<_WqNZ!E_U&r z6hOTIep@Jwvp+JnY&(WwX}$wKqQ*x$4qm=qXQe(HYLcQND-Q{swRAZ>W^w>${O!z5 z#uGc{srEO;ZKF_$(0KBok_xPsIKPiRf(+bT8Kgkwb&H&rj?-zeo0DgtV0=xk%1M5} zzuTyOb7Z5+W=nKOWT4;wU}dRNX8@Vk6Z^>3d$SwkIzr&d&j~7DzvlgPH}u%9v){FU z$+D72Wk1;vFhguz?Vet%tWHv^*|h&0m}C#oET0;~mW9lSxHNP0YV{FvD%t7=imOmz zPDZg<12A075w`z)agf}ek5a+ZrhHv=0)v-a8UwHTIT1c$H*(&Ync{;j3=Uu}x~)4;6Sr3H zE^)-tlgRofL~9PGl()slt4l5&bkCWS{e#4?00sJip%YD?|^EpQ*=F1!SjiBNsri=kf^Awi`2$T3zYHZVO&e zA?i$VHb85IX-B-HW*)O4k#^bt>uQtsq7QVLByPfAGg{6Hi9LUXIO{~`%6Nr}BL0XhFAnMvK z%V5@q6z5uZJCFxFr)uqN#AbX9P@kZ8JH0DE0xNjNMr?0S`XC-Ht8Hzn8IKRWoP-lo z2VPp_lat`sO_b7xyqVirEUF*~u25d2G7TNiQFlt{$^SOBrliDj>XOi>?*8VzX#%@DnQV#uX|7_PZlU!@0 z$L5)waslDCCMLR799}`C4>~)_YciTAI^oVAr@g zt&T}N9atNSh9HZ&V#ZmGMs6%i*b1TnK`#c$y;y?+MNg*Z*!P&yWv^#Si0o%za)*RH zV~zn$R9%aqyW?&Oe1M*re+Kxj;#XHlf>NSS|1f@E2PM`^p)%4JU((VfNuuN%R0*o9E}^n)25Zx!FEMGs zs6Di!kk-@8t1@>zC@yOj6PCCLFVd{4KWYTijEQASC;hVE_uwEND30hZ0i-^mb|X2h zV^J!B*wsbOxctf|HoZB}^xe)ODjr(09)VQtK<50_Zrkw+2<|Lf;&UqHJ{Zz|0z*Tm zlwC8S+MW;eDn|Bu$+&$9d=u7uBFFmwJTf)(7&M*!zA82O<~s`fyEFQ~0IGuj!BG`5 zbhb2BadokGvNW{$r?Wco|F&?*DGabuiWNi@CDWkOr8@11^>Bm|Bv6#0e+9I?m^lBz z3d%@bF1q@l^=WXU&2g>#^yhnoXxLy5{rS^^Af>Kus?+z)>G>?1{}c2YGAaTn09gon zb$XJ)Vg;>%O;H(dY@2LL$+}VX?@LtvVH&9LTZP@}r7^&OL@NQ&thr`D->Kp96oB1i zyD4!NMJ;@L?$$X}V74L@X`QCZz7gTj5pHnEXyl8z?j>cwU{N2qU z$|*?>@;yF02AH?DDXoQ8s&?GHq-X0i&TSbMpKh3|S!n2N5{>jeLd~QiIa5E$4ApXT z^H)yz@M(loZd0wB1I~5BGwl9IUG>}-25=l&V2{yqtP+EExU)wW1c8Cc*E}yy?O4R! z$W4^7Cb6pzv+tmjHK>H4lJb~hazbk?jxIG=t(Pchw=QJvN2ir|s>a6(X$cOlVIEnd zc1ovMtf?5uN@x^;PF|)lbQ)pG+mZWGBwvh_PGB64g}%=vnp7FGA;-thwe0VU&~>&n za3#|5Wz(T$9h#cNKAAN;*j#QVwMsPTcqGZ9Dvhl~+VI4WAMJ*cFv^cIxscLyIj$42 zpMnZe2r7$}7Pu;#oN<#HVt9-oW;GT%<_}v^ow$c%IhAwmaQw=f;`gnm1b?a7!(=KR z*R(zx_}r3FWLB65)RZEcuN9g!1}~v*3>~FRJ0MiDKgk(nVqeZGN?RgK>gxtHB*aCi;mm+;!AAte#5YgZIVQn!y?t-)5m za7z4C^H5{fLdeKyI&CCFccJe%D^|aY!axRCRDvHX!sSe@jfy<%V1*fYTsmJ7iLi9k z-hZTVP-R9;HqP+Y==;Q~zBay%!)WAJ&!Tp7b>`NAZ0)us-A<8U6fnPn&z|CQ%^KVP ztd6=Af&zP*zT@@+@#u^$PhG;q#@QOWrbdQ;h4-R>H$XJx-%S^Rdz%DL2mkx~>g3*z zQ)=HX2G^QG*&`24>CP^mV&&Jq7U75NtF6nXnKTWa_dK5OI?Be-@~p+w#!|}qK%cJn z41Z0u$ScM$b1rqRE=^X@Uh~6>Ahhyi&XzqJywd1 znJKc)9~_sNqSG{}M9Fc%fNybbOkbE|@$3vo!14>Gik%By5l2GJCRrt@8j3}V zGGc{b;cKcb&07pChR-ycmf}!$*g(vT&-`ls;UJ{Plg>&F;4S*DQ)xYd^4A9)h`j0F z4v&bLLmWWGO?k?G2EhaR-d8bb3%l#j(qi)D3gaKu%zP3*yu6GI0F{eDQw$fXq#!uyAvA=J6(&Nnorn0L@p)6Ri`VfJ|~?^z-6OV}b#j2zznN z5{xR|`^c=;+5J<98e#ZNoyk=iTTQKlwcU|`Tc2wz#0g#|l-c#fQid*yHM1y9mf2Z| zY#+IndH(4fc&rGKy>e!|OXSE{UU`drv!|@G2sOr3DTgnHJgv$49G{|I(+zic9f8DV zCAinvk+Usom!iHG!K9aWyNbalI-x*s$;!oKa#B-<(V$ao3(cEp)qs5RN9wP#>okH9 z66dBME1>G>k*>oe^~|cMBsNeGwT47ky(S`&R~>F6;x-PmWd9DArAvz@O>=hSn!>e0 z1%wFN1_}VH+(V^TRI(|^YW`OKqd&Y_hp&^J#l8%_d2 zQS*z_H4pu=he&j|a-_B3lSo)z=YA@7q(R2cA6Nlc|9#T_8>l=rJz5im>#4qj4&(oybSG~DjUFBn0?vgO*kjb zguUXO7QbX5!8@|lxg^7vV_BGg@&fB#!kzfHl~v-zAAV|ThDH|$a(VUaVqBpKb^rNfD#9f?^)>8 zNsC)fcz3xw;_C@RF4P&*9$ws%jlW}#5da(l6#R}E#}Rtx0grLbqcl9@-5BKveM}PU zBxS&O@C+bm)v(zWr$bMF{@Wc;?YnE#7@9pRgcondca*4eH>68xdv&K&;w;I2;jYF*&@R?u(V<08dn z$F^t{5Na1aq7Yc7(E=vAyvWI@-n<|xVj*FDb}Ey3>{rUnO(Z6gR%@h5mKj;dt|5Y; zIj9}J{?j!7{b)JHs^J3GVg7dArNcj2&Orsb`^p>I6n1@S7njYokqw$ox6E%1>r_nF zs=XJ;X_n|Veb&7Z#8E)((0W{5Q8*-<(Un$Xr)bYVE-F>nlkJEcaeSOB^_P2+?RNX& z808$%1PRMhHMA{Ul}kQRK56VQec~Ssaen*#OYMMxW3jj^|JBB>0^GdwbcT$ec{0u01nDhq6j)uVxYd6CXbp$K@#>-ku^6(0bb4#LMES-T2Inq0`4}`U1;n*7O^q;nw(e-TC~M7x+rWl^-vb`U1%2R+A-zC1XfZ&OxDC9 zbE_@I@*>xAQW-NP)?of}uAw<<^$;D{MEPNaMx9Y+WNA-msLGejm&2C9Q%yjU%0)%N z9}9O>`)+)&o_1$raqEuM2N0wue*6KPnbC0=QtkeA=cbgkncQ6FFpfvcWuK*uODsHz z16M356BnEPV~wZjaRUN&=gJGDo_5MGI-VXAmt1f#E9sQwtp|B03Uen!_7V>NGmRoIxQgJM~y^9AEdYwPgyDq~q*V;i=X( z7MtuG6H4?WY@ch(ZKBTB)OiEMqrPj^QCw}l(>&ZMjE-aV71mkyrA^OidZj6!6Rt>Z zFb%jbm9D~=DfVPx=gu$cDGA0OHxy;DCUd`%1 z_leiC7et9ZC)<5F_^{$w=sTU9nm~iwRgU^*(6UnIxRI%&H(ub@jP->#L{iR>rd@awcbn_#lR!m2aC zCYq|z8?jK6@3_0Cp*k`9UB zx+!MT%A2z(a=+$L@1J=z*|IN4G~5sfdyV@k*DBW@drWgMdl!i_ zBH{UdG^PQ9(DK+a!4Q1b*dyZ@$Z9!9xgkR;h>Q{Z9i%~z z>;M)sryC#(F=44je$PIQ;fSs^6pmrTAJg^<(tWd6TfYoAK0$u#U|ev~$7|T9wdT+v z$^8#2LaX&>=u=q4EL}xlk46o4^4^I8b%hY)!z43)bztOQF;&EH*2`9J5J^4bcV7*} z2r%PFG{6t63p+8Qk|58V^(aCmoSon9s6HNPS&TB*@+M9xe;JwR?Jd>DvGyW<~>V#V|IWHu)9F`QU&S~z2E_qbt zuN7C-R#!(|Swzwoy&A9wQx^#TRZxh7w>@}BA*mP;S_sPS7xSfK;ExZQin%6QNG08> zGfC(}KG7vCoQfZ0MZKY2_P{zKePC?iroQKzSLZlX&=(9<3#^}YBzpz!^1-IxWq!uxqbB4(Ao)fCX^~>wvW7Ma zYF#-J>N^vLI4+>QgfA1#yo&lRpuE(1RBLbg9Y*}DW~N)+@nBu{aJ6->% zgFAJ4co3qVilr4?Dw(82(=6OhaT$7s5pkQ`|3JO_%G!E^bHCTL{=9X=di{&7p1;QP zV&~}v3*5*F2_4R&(;XhOYIs+DsumS9~ZJJVluGH?- zgHO|?cvE^xP_3HBrPZWP zVk!RZD$J}}UUI-v?3+b?Tv1t`W2P7kC-C63uL%)<@ z2Kmgar`AGkgGXbd_3^3lg#+6kLD&}tn(uxbmKb7GnpDr(CC~&5a9FE?1+3Mwi!0@| zV2BwZQdoqwm44ukhr$rW(8s#4h+3>#XrYGJriM`=vPpiz^DM`-x>?8@OnsQ*Y z=Di67`w`9)px28eJA@ExlI>ak#PtbwgBpiG4XhSxm~xyUJ^QA_Xr*Nqy(7rWVWJ*( zgsaUiU6;)B+l*ELusCP^;vz>!Q;4$C3*6w(0wS%Hq;wC!8*pLc2n=b(F~*!IJP@L) zi<=lb5%N_{fQf4+8hx)X->`Jkl_`8F4KYm1mP+mS_Ueq0C}et3tg%ICcOVbJ6oKHosxLc5==u-?T&W>`H4<8*(~>FNVc#PAnRycoYT}7KHAE%uxNKA4BlWRm zA?{25E2&s}^AsLodn?;FvB|5K@T>fF9S1&mbHZn5TEmB~V_+Vg(lh*|(%2iDd(ix7 zfrKH@Bs{IKH4O`Pr&|?e|Ep?#0rkv10~SmUG0~_RiNAN;Z2VVHHJkB{e$=%Gvs;iz zylKKc2u#A2=xE~~Lz+FR0`$QVuc~$x3I1*etZH^l_Yr`$?DG`jV+Jxl;YJd@^d7cX zsYghO$55$3x;IKBO%(ex+1Aj}*?5!e9{de2apzIc+b-cjFU zT_tW}8C=R;Co+C2#pdja3?jDislTRpe_e7;c}}(*UHN^!!*nBPD9wZf1rz{$VHr$# zyQ_K0hv<)y*YIU{cm`R*o$^uaP2Jk+E&P?=|FmT1^TbTEj z`T!0G>z$-&vybbjDgb5XZ&_^BxYoKWZ)#;|1rApfG?*5uU(AllB#+CZ!fT^8`>iS( zd5q$93&7C3C+39BP~qI5Y9^r)b3qK69BWctr0)z`^u$!uBze%%yKp-KP{%REfc?wG zR=%mRg#c1As-Gvj+^IqC2c44c*Ea_jaB5 zZYJ4dfv`(Eh2a%a6BeT*ik?iAM8_O)FrIZdW;pS;@-6Rs(Va+zZVx-O6ZS0yVgn;U zVKs{HOfj{hgf7UA;U_pAA@5Q>$cV#>1r+|g+wk;odPp)cHF0ElbJ2DyI3D})B*YpS zRd3s(VzN5^x^8MIj~0dUVD_kBA?6--=Kw8L(E$wIK-tuW|IjeTy1=U;4b!ze@@!_e z8RgcS)D{$EA=iWAH*h9TuV$ua8Y;f?6 zrasL+wRypmdjaPpR@_7;zDv++ZP6~6o!d@HIcW~d@>H1qp7xth@H&o!Uo9TXAceOg z?i{}(Gyg7KzYitw?o9OBSr>ydlx2xmRI;@bpfOK zh1*kdFjm~69{A|kC2Kbt@f@aEsny+0;R4Ekw{kx?u=kHE0AgU|a2DBdsUnWgA5CKk5RY+UK!UxwSY zFp1WU-^T9Y@7Vp{{J{SmxBnEgnM&HLd6ux&B6A zh2TXBW)|@M<~_!-_b(xr0+K@tn=_$qZLkB03wzL)3>7$QM|~57@^GqQKavNjd`(2- zpik;0ALHj&Xi`{J6z=-YVArS>?T!Q&BOAQS#V#ni&Ez&^joBH3CvdR{QPNpXR$lFey|EV@iRIyfG6GP>-#<9T_g!~ZzQs|k`e~8r3Zz&9F zS-DI|)T^+!+T$&;RLekAyB~XCvaY{Sz#Nm5`tI+0EPuLRC4-NsT=ZIlaIx_pS^MK{ zt84Rzh9GAYVz1)2{VO+nC+%$E;Lu3fu7%D0xpVz~y>$qO*0ZkdJ25umj`yoy|;I=48wQVTEC`Un#oAIY6v6+ z;aBH)l}w}{I>=J@3Q@?@FiZKo`pKxEJ8nL2RjJgeug{!yFkfg+4~_Pr%C@Fw+Z@^U z>$Kdds-bmRl3q2tU1lp>xJO>-Jykhijle=O+o^FK z=fm7b(o^EoXbj-9ezmJ@x5hj^l;q%k;*5L+xzsFY1*fQ9xQntNRL)RYS~*)XD_4{{ zv(Ekt@-YpakSFgi|1%{aPQ>pYP98FMKx#Mp&$s+0OX7E{NO@}^n8WnAgq^%NQMf{{ zC>X*N2t$XPAFt@f2t=X7I5PO#UYtl!@^}USGcF#1vUhM8n9$)Lmz@I$T@XNE0otfg z^HRo`q{n;np;ZR>C=zpaVDTo*vL0k0K__(37J>mr4S?bwr>w^s#TiCH?9p(yKJi|& zWWHjc!F%hi=Grdk!Z*Z>%=H*s+eir)v5CU(&k*Q(5Hh|*7JmlyfoG+z{>9Y^CL3z% z^c~Opa6mvb|2C#QzZdS>{!>mb{FV^^V}TjGWQrtg8n98ms`44Be+sk*h&`bQEI@$y z2V8w&AH%i}igt8Nu0`6+ zNrquV*dmpJ13D|vcORV!OVZ_TtBSt$Sxly&n2*H^MkBSEP6Zm2+_7N1Mp|ask}$Z& zq6h*)G4^YNHQZ^N_oW<-hI9zu(atDB^NUmMlzw0o-Eu*jaiaD?Lualc>_p}`3cFjb zeek2688@^jJxyK}9U9;!tB;qJd65N`gVILo0`?c8+TNjxLyQo;$=0<&CS$>Am4bVH zN5{)r0?;;>PTjmx6Vw4K-gK!`TWP9In`As{wK5Z~Ty-4yW(~Cs1TXam^o9(c@qA|t z16I5awl2&ojqN7`9$KFZ_^b2ca9KV~&z}}6Al$>tYs~jl*uZxU(v58L;gWMKjn5<`hH_v4b}9mM8E{Hukx}ZcWY+E zGobb}OtPbPr89wdjZUzZi%5IrO(hGJji8d6LeTBT1&s;zGxpZh#Zn80H}pF+hjtxF zjYTUeAXkGj4l>tPQ%Vc9<*g=s*)YY9?;ncK#)n#~?~N`L^ez<#U>=2YC$ux6Oih}% z$a=f5q^l%EI@xSsdYH;6*2>%6?ad%CwJVm#j9c6edK0Bb9L3$;h!{C>#Ty$?0vdxv z7YfrRBecG6hdUvJ&G%ZH^9lx;bcQfnv0Ynic=B~5%~~3RXE`!Q_rYI}66bB=-k5ee=wTy8(7b^TEIq^~JQZwBsd>JqM=+OD&euNWPyeEcWnyu(f^B2XS&I zG`4?=~SZ0Ox-euHx@m=#RZj`vovK>dg zT@IhT7RC5dbYUySbskgW6_Xmh)WNZUdrfy4JvXM`nJyu1B|BDLVV8cww3ttj}6xaT8S-xAiUsYfio89Rxyp<+MmuSVhcT6F(X(G#JgWRgsWLXqfKv1 zHG2qK_RFbHJcaVnOKpIdxF@IFCE_4g7g$f>9`oCnYLvHLzA3Ip@m@YlJbT`OnRgVC zzRjBNc{srhJ_Q5b&*N^()eBf5Orqmt2l!-0p=1SUsNc?r?NeLbv`AKbt+K>qVqmDD z3qZW2G8*5i3HZDq1j}Gu)8o_80%was5Okt4w2Eex75uzYa?#)tK7pLEwh@j;qQOmU zV@ei@2va`|x0lfj`($>SkN_6Qrq6(Qd}J=+Sl5h|KY^%8IJ*ui{tDA#lpDfe%pzcp zsnCWI(1gNZ4w=vfp>dOYj;j3?O5x&Q?qxS6DtkTR?w0##`Kq&xaYKek#H~9gH$BEA zOGf+ucp1>VBsTt?mXPSOhwGT#5uXS9K|?$YGNF*{kyHVK;*BxQN681==qFVyFVH@^ z*a0G5Z(5h>PeUPxpvV0PFP*FB=Ft*@Y)CO~M-2nJTr@j9Ue@udDj6<*zDmN6cnwGW zm&J*8&(qsSP^f6}KYZ%#r(p>a$#UdX9jLieCEb^E@#i?uXH61&ZCpa0v#mk5&pL?M zIU;RAlS&wtB>Sg2Li+QNyk*GPUw%Pe9jsh&2F!%ZEaua6JYRp}Jp@Q^Vm=#QOW{8} z;66OiJ|v~m!aq^n>;jW`bZp5FM<)grxH&KZ3cq z9Q~%}o+N$cdz~8lR;u&Mr|}hxKcz{41xm9S_rd((!i35~)p1g1)~d^SZN9yVvgli| zAuU^b?n>I*x|__C>ditC62MJX+Bl39OfJ+6p% zQO$hrit9&V7EzHCRac{3f==(_o(Lic6}V&E{KpRqHQT`c z_IYYn;;)ETRQpjm^?NJVJj=Xot|HYei>hwWxUc#!W)5n^6c*aKO!VVWg2{1`q!uV) zDu82_$XF{d5lR4Zu0Vif9B{|iXyHC$FJTFx3lm4-F0@!nVq6gw1HOFyqDR{Rq>O%wcgvn^;oMhQwjh7(> z@7vwt-gUx70eusUA6spK@fOz@VkG0MO&9s);mD`?Q|cNMn;;TOl0}lMh~c7=O*F}s za^#8Q>5zVBD=mmR68bOX7CpVEj1?GoU^bzex9juwG>9u87_Cq)#DG*myxyVt7vXwO zgt#J^5xzSglJF8(wmrlR?Q;S9?vpebfYU@j1xnlzk%?7 z!++ew;z#jDC@Xd~y=$%~vPJ%ywQ8ns3SP@G^ews~|L4vSU()$k<+njOl<5DZGyI>C z_@A*ip<(HwJ%H9}T$yyB!KSHz+%16IJ~#m$i5EBAm@%Am(6455j+kNovZ6*K9d*Co zFF+xy-2?|pp4*&oNsE{SOjxfeA#M5nU^LR*XMA2|R~3(0au(jF&m6xmB&&ni__vzItU#~RP^J>qXdnX+m{m+%S5g4DWhWLwv;6IHGEGM#7Lb{AE(AhHC?df3SwoU z0M=YRRppoTFt{qsYuNbk@}|98phRV?l7?k_@^CNMl*F<)TB6QT8YkXSQdw8IF}J#L z3J2QeeqLsK>&8_Q#%GexDyJoVHcN^EH&kXN&f37X0zn&bE=7V2LwFidMRSw*TD+nX zFO737hO@C>fG{UkGP*p6e06ZN|K`(^v$b{sH~+@-Lk#9a*?qww+$y6!)J|-7PzfO^ zS*FR^OZfRtJEK04hoX6>V9>TI)6+UL{&WOJ6}lKw>=4<15TlXPlKTa7#R0&NesOff zGU+0R@?txGUI4^@dKx~It(b+rCl8~vTju8A?9Swre4f>#G)ZGC2R%zCLR?YmC>s7F zd4RMK;B-6Ud48FrZ8LvTK)0G1B|3=S%$h?2d@3k=ZHnP%6diAuZ}$@sZ4PG69LIB1 z5c*-6V!uF7h^-{V85 zc-(82M^LXu)(eZ~!YX1-?%Aflw2phLt{2?w^S?OO4duq)YKQA(!$a~vSPL)Q!nTJS zXZrsj+pFfUrmcMb_@&>Caqs!wNoVg~hww0S4rgayiUB$j1ODR5sFH##t7+FuEBaHo zPdKZ!HA#2y=ox?Tm};-5?Ojkm-Cp~!2semg`4p<2)kB+ET_ysWm%Dr6VsjjfnOMEN zsiTn6db8I;GM#<-;{UL9j?JM(&9;th+xCua+qP}nwr%btJGO1xw(aEPt$S|OJ-1F( zf0%z@uAXajkMXR9jH&9?GC5(gSrpjQttPhV57?-5RI4F;%VJW&V?|I{3IwA z??8fg(vZz;3a}5HgH?KUS#PWoAS=Cr7agJd+HdXbga?xwOuR$*9KTRO)@1)%{7=1- zaZn4T*o4?@6j;Hw+e02V z!w)$6jW=NP%in_AcqBl3nD|3WZm!G$94)0hD4P2XW>V(WDi|qiD32&iRieEOl{3Dg zJ1N&s#|{&v`R0tUV5Vg}j|BS6XGeoW7!kt=iM0D8Kn8>O9kr0qPpO%sh(Rf-U)Hm@ z=n+?18T%v>V>)zWt3pnh<^JXbbP@UM~MBjKr z{q*Mmk-7%FR1KEG#~e1cqyY$bKZWa9^UMzOQu;W3*Uj$KRpHd-&+*mLzC0tI8mvgB zXgkGUymZEl8e`Th?Cqo&2;!3veVE{U<4T4Xl7rT;2U4YC4JJ8kdAQR=A0-MRzj*t` zh-eFlDC)uT-$;5=ZcKn4*2>N<0bDL0g=7~UVF?oD@HfoVJyP#KNBJC71Z;jOBcoG# z*SB5Cp%js&%)?reSfQOe1S5pxF!f*@7V%;P_za`qgmGAh8-zOs@i)QVqXavkZ^U44 zwxjqgqhW-8lLUS^_vA457>9CLhjI#t!)W#U4-4rP{cH!gwrd)OGm*4n?!UXF(5HCY z^rft`UCzmFWzP696Ja}pyx84tx&&G$8spW?t+eQ)a~h_Md88*ERHFs4i_&k&m@RA8 z^JS4UbA^@{7MjP+t<@)|nM$1!=%F+rP=ze=9ly!Po`c4~y63iqV1E&ZZO|^b&eFqC z@o`7OBjzC6^#+~EeZZVdv+Hv3@*!L2`8^&rJP~GmWjWI|y&!(03=(}&I@ zI^7d6han&S@uh?)_3BFo*#36``UG@CD7}Vbn;;g^8yKTTs+FKL=)~iyXNePAxowmY zP@8VDCQ({ZAzQaRDL77asXiQzOHidWpgBE5Vq)*TakLk3riG1MPp9ntf&Q5YPT8u} z5pWl5#GXsU&=q7}RWZJO-4{HLzq z91k{%1~Te#)a%uF&f1;w`X;o~boTt51-NhOT4zp>j2<|>13}3e+kf$)YU*uksA_oyp|Mb_JQ^2K zA&Bt6m15?Avsw^Nse)fThB0Q>EJR@()U9U{>G8lJCH8bBw*-rKRk}xx{08}oR8`I# zZNriUb&hQqW~VX=yDhgKV4i)+&Uj7F-2bZVptpwlV^kE`@bBKo`o0YfK;xd+PASJ| z$Qfp4u;rMb4Ov4pCY2u6U3`uvjNMT4NE$5Y<5)%+aIK;uw62$Fip^CjH$5f`tcNfPt#TCXi2cu8X8QxV|->_`U*$@`k63}}?CdYP zL$aP)D3W$CPu;R}Q#lynFbavphR-k)h`pVmh~Y-lN70yM;li!!Fh-4}jiWT;#lmTB z6j?N^7YA?kKHI|U+}={sIWh*!R^nNVmWS=sy>EZXxsJDek@@!;oUp(i-mDX^IBo8< zreI~C+)a%81>AC1F#oD{i?lGi#ATLJ$5AG*pYyz5Xr)}cG=(oGC*tJPnoWWAz5qd= z#Ef6_$^*ZnYd=A&zSU6ncX~hkzz=`;fgj}<)_NXmnG4U{Wf|WP-%DX;5f2}OA!ZSc zU6oPp3^WF*uKUM`WL402{8W=43^b;>`JpLJa5d>~FWs@5TxA!hJoMkWb>dTA?AFR) zrVHf$m`q`C$TEmDE!oHfnKnVrR;}Exr(8*~u2k=<;W^3EO%$0-N~F-_HP-@J>eE>o zgoLXhUKv2ca&U+D%L*`y?<8=uQFz40xfeX(T+el6pr{YqmWth&>gL}_V&wM0$@1et z3OR|eLKqfuM=b%TxMm=srmRgv+8VAT8wI{`gecd znbb0HiJ&tJVLJd(gSZ+1CyGw(v>7v?9|+e5y$qjY;?@#=P7|87>6cisbO zjQ~rU@Bzf)g7%bC5^!RkfdL=s!10sg4~dLRqypuzip2fM8UTBR{i>ZF~2ZCSy;eU&`cC@H(t5IjGK6k@TzQ5{pXT)`lcd6I1A{iWRe{>tg;?PZ+fX4fx|r*E=xW6SF~ zyQ?GX`~B;R+@D-MvQQ|0=4o8?%66)}19jm~3v7)lV||L~R!b)aNIw>eFbI)T+rFf& zOg^8VAt$VtH~KE__W2WLoWZo(AwvP zwt)WbRE4F3a}jyu1J#z8?HI~$#Fk{>lcAytJp$g)^NNYOP`MqUMa6!Tz;X|tyd|B5vtL^l(qcN=q*E4jFGeji@Y0g zxtlhgTjD3V!4wrRfHR((6OO`%|P6;e&^ zD@*Vg^XbOF6Cf-+Y z0eqOV*%=DEP$QO)o8&qkr_sHJ2g~l1W7@$6??GmT?;$=@+8V z4_dA{wYCK%$$saQzS^4!zdAe%B2`sbRyf*n3R#RL&%ChNp8JdPW@KXj z>!SZZ`a+DVh1P$Th3KWof(r28r4Xd5ZNd(LjQTg(Gx8Uk zHLch>Zd`X>=q>ZW=XkH+Pvg!P+{grgAeZ5p+>SS$W;|v%Zg^h4A8ulL0J(#AfGGqj zLK$(7ZXp-58BAm3=W9y^2aw5)ClPP27-<*QXywe1OF&`@3z25 z#bh$gKm3LYKbg`)Mk5n)p+bu+E+$*Z90d@5j^6eKeTac9 zi*e&)j!1_lYKYhcG!FPyp|4`3sAl);!@1S6;3}i-RI6HX`p2{?4Uplw5mLx^5#b0< zu8tig;O&2e=fHGOc4&?8m?J_ACY$`JEHw;VKBj!xNegFlQ^XXs9Q~U?^+@4@V<~AAdVOA}B!E8_wR;gs zV49$KtvBxo?IS-z2;o<^(x8L-Nl1G{Ra?2A4CDRh%;8-8k6O@Vp2HKOEQZk5tD=a49!~4_f#XK z_M&9!Xuma<+&+4<>9C?ZIwQKHXvRfl$5z zN!m)!)KPIA5QD;nM+!Gde{Vt?Z&towhF5krF9I10=~qJMIFCGK*i>ph8&x>6?GVpp z!i>vQ4FqxNqQa%jHoh=0I1tO0aBS-Cf}mwCei&t7==^Eiuxa)98jWvuV8UxmM&>TL z6b2}>*Br=>HPe|`l4^cW63sMiq&$PcWSZYHn>lmGqlZwIZ*HyhR5i1#Q~e#Q>i$w} z`s;mB&GssZOG(2RnULr4Sh%ScMU^MTV=X@T}@)taj~=!*r>NoDCRyc^Vim7h{Yk}$jegFt>2 zUY1tD(NEqKHS=i|5nSR_3}(f);5WCS#I__x1QkpoKK=Il;eO+%R5%{i>H;ApwP}0X0DH7&~U~i{{1~5Y5z4ea!|cLZ|Fe*EV3$=wr;e67S_h zlm=NiOjT~m1zN-sqzvWOc@nkH?0Am_aQDSEybn?-`EGZe z(I!w>z6OhJGs4s5x`XjKqBMfm}I$J9a`5;^q76u(NEDr2eg%#d- z2~`eGyMTg~$qp^dx1 z%R?Y-P1tRMyE7WDf;aX6uZy|(uuk`hR+jUjZVrIkHwK^Z_lak88^Cd2*|p{mu&O`q z#-`3&+%;(&Y`(Zn(e01n7j^C;JB0(O);kVMUX;9t=j6`Pym?1n@WvG-r}x42K;wF2 zUK5gEA$xY&n7_dPXU}MinmN*D0|3}>_=~sfSEYFaec=OwP_3$E zN4>07*;H*)UHx3or*v`m(QULdJw1JG%HjLt$CoN?y50HGRrBJLgx=$GSq8w6)O7+1 zH3>2hNHaUmEj$3=wdN8Su<+j0UKx*v<&f9d8u45~!<>h=BuB zjlc7!!pNIF{N|N47T$$9PH%fodjqi-JxdGt+cn!jSSZoJX~-XoUUq#XP1|pbP_Y`^(_zTkgmkF+m0TCok(WuV=LnxmMs0_j#zAmX}RhGx! zlQyo)C~v3+#1`vm& z_p&OGSQ?39F(IBjSE-Yh&z`-E1<{~(I++FoW~sP==C$3hiFLnnRs{p8|53mg8BRtb zNvukjJm^B(tTJ-CcA_LNEA ztMED-xX|}qvp_}qztfw3r0z>1TR|)c8`-80v~z zS1nL1i$Mu!H5SjHaIELQ_KiQfF{Pd}xn0ugi!KLX2$SIx(Zec#GXlrsHqK2#`OkHnQ(V5ja&TWT`wq_HUzo^Y{r3A%A(&9u)xi!uuDd& z1iNX^Q9wt$j!idhOb#w?pF9a%cnZbA>j1RdfSh#eNTAnVH-)@m;`?*BA5TllF`4XW z$wg~IRSSKQ=q@K)`fYv`p|}hfGM*^kdXO8ILf(a?mZo5mBLlPVVj$gW40mpavxLsq z{m{e79u4N*1T=h~Zf+E}sJ@|uk7=jwS-=Qnv@l_0klbpPy$-|R-ecH6k~{mS5_E2G znLIHNqTeVwWGFl2)pw=t*2wOgh5K-Dp4Kh2JDLcu1H?UG*E`ZrYB<6f%V*39tvjHu zu-H1C?Fjg%B!sj(2i^N$8z?csQGjGNWZ#TL3#^*=XO}+ttlD5*chG02^{&u}jIEW8 zV^m?!oL+vCL~I*r_XSd%t)gVM-4*Xq zaFF5R$cdxq*HFlwJ{pQ@bsA{Ul`wCcrm3mE>1Xl9IzNb>qo|x-o9P?cSB!50r{LE) zjCU}&fC5)w!ausx0epSrWS?t+a(nb3$2hgbiGaxv>GfI4?yNVxUzxf8LX)nTWSeJ1 z5?vuo550d7zHR&X+?~&d@>L^MR)O)eZb1VQ52FT^mY{zEzuo|DOF*}7@rAcmHZO1Z zL$LEOF4t|VF09ex9fZ)XtslaKBR}<^yF=~dvlL2>KQjL`(@{yhA)$}lKtxNzU32RV zu7o2tp?8ylM2J(wRbPODh8rLXEa@7ciV!>82lS><mg1@0r?hXa(jy{Le&*BZI zynTJ6Ve*3&5)Pt6;3ROHMLUHRBXo&ElcVkLz97JuzBhul9tzL;vNnSe<0Tp;?wON$ z21kdX6d2pUfN!L|2^#oCNr;v>o5$c*QwNs4ZrCWs0^x@f^>wXsuCqo113pE1d5T3@Bx%0X(rPe#OGr>I z2<8%%av02u#L7fX_zb%uJL^`7SXsH8wq~f}uthCnLXBWZwrSOqmzk#~R=4JRevpuP z)lE%S~|=P~!x($Cpi;=u3<#}H99NZEKShza1I9uhzccnzb( z*hLR>q(V=L_~2G4*oTZ9vd9%c@iGzCgeedxk4EgfoP9M`@7$iHo^A5#jZ0v9aOyv+ zgK3;oL>r@L7+m6WLg`rWTcx0R@@K28N!clk`{A)i{60HGW=?zx2zhEVM|9Id)6elv zf0*|EO|_V`@%4ifFmJAA9(n^US@hWn8y3=iAX}Lqa=%Ur(FvAaCq;msthhQxNYEWA z)&Y}p2{<36#yf-yqqAz9sr z&pNzLPRO*WO1ljFB5OXw&W<>}=<1T4!P@Y_-Gdb<+29*#tTNxpWg3$L5q;6G4eKQ0>1thA?d;o`Upr?TtE3$0Z|&1vmDOz+t#Q9vM25W2 z39ne-K7^f|WB3+EeoL)NUR4UZ&90VW`|Z4V_i*hx3VsKSe4%zVTBZ|?HYE;9Or0!H;m?R&PAe1ZP{LZ42x{f`s&vcOgzkE!=6($Y^-x?!;U4v zjo75|*3n&LLg`|#1;10@pKJMw@leZss?fAq5!TKNzC3c&epnG?j5?Qv^Bk<9X*tsi zc}DlBUB}Dc(}l7K9s=0AVD_k0Tw(#MC z-*iLL&=&rX@$?rOSx9W=R-al!J|JnRhaMP7#@_UWc88@(3`M+T8pu{cMWxP3jRmDZ37k|?wUYf4A-)$cwp;j!tw6xglmP}j}b2@5HtYb2FP}uheze!qDxDoLSjc2%+yf|9= zs@5JT$9S&k(bytK*i$b`;E^n4MQ>54fK#6>uitTGAP}f|xp<0Fr~Uvnsc@_ET;Ln` zsx*8z&OUjS)|qEG%^7&dQawllc#C4-_t7rBU~V<8PqhaMZxdJP{3c}hf;i<|R8w7) zGP9cCI2_E@$qezq!%TyF4b)S^Qr{=U<Ah57h_#*;PS6T5xU-=TfnlJVG?%t&9lRQjlG zAxYnOD)MNU@jgyLnK{S4u2rm!?--~(PaHT1h(3prjU2opROo=UeL~Vk zfe+)E0=o5R*M@p&y;PwXxo=BpesE#vd9M_JD_2{(;L+xMha zxZn~Z#K!_Ovpb*i>S?mj(+4cxp)NF(xetis;5^OKsf#V z#!r0}TEZZWg93QZF_%Y$DAzk(=t_y@D&>yiu0-S_lHR7RMiuTE%qbHCx~ny$Ba z5pVC1Jk3Xm?!fH|$QmeNR%Vb}6L_EbV!5&^nxTo#wD0KeY^{C0@axdVtEm#|kkL}x z)RUm-wm!7vn9WfB4nGMqtt7t2KypwB7opm;3gueptYo zf7G`)0>X6e2`9mbq%^*;gId)}ml#~c3X`ULA6;`9%z1&4MY<2u4{pJqQ=L`f`Su)^ zBKcE2j0kYM3+vC%`h#WuSo&G?&v4VN|Hxr8{}Cr+Jy(rjRI3bbXR}g${q-gX_o0|c z4J!);Xv1`LeLn8!+f{U%K+sTIl!hcv^pK~J00s{TI!hXK)_Fl6VGCI}ILQ~C$W1{l zpamf#fl!q6Zk0bel@IA1$auLZ)!DOeiAGwz_XBFWm=`i0aVg^Rg7QGNvGIx;|2fEQ z!WFlA1Z;Umx)laTN_WkFxTT;Wqv6<_E;WC62$t5$N?IX%fBKe*~ zAzS zOGjG;63gAYtu{C9cWYl(sQ%d=s2YUy;Z;GOo2lnWvir5tZ6D}mCP za49=l!iC@TnqQtveDd5YpPPrOZdco*J2ln6%8Ev*&8Bn%j_2`#CoJN|y^R^KKwUYI#n0QClL3p*qVytuvk*NiJLSzWdtszWthwP))D7sS{Ar+YAj0V7&D|W;;NCGG}gsYMmnNHipx6Y zptD)(o7~bi++M3uj8zQF8S%+;`R(gGSyy+T3mS=&L#e{G9!|F4Fv&9&Z)kN`kCRhG zc*E)LfN2Srid)txHNwk(l#qBI@obQ|%GgjuZakh+Xnqi`7fY8|d>L|_I2rHKh|~kS z>>AxwW1dz`4*Ib4vGpa~43nOl2bgt(lNi*@igBL#WaBpzr5YTv)>`i{3$9w=t|TnE zMnvqzGV;l&Fh+XDOzX!K_NKL(k6Rb`gih*;+B!#=-Q9Y;ukL!#nU3OLOKmARxD=z? z1EdJN!>ZjmGf*31)&hE2SA`#Rz&9(>ITBwDR`@hO^ZS0&5TLG+M2xOBwLUDLVVcH^ z?j`%nUVTFBFlzyjhVL4~3OUM(Rv2BASP1~AW*s~3y}1lt`PnKK-Pve zg-mqe(_%=xgY~f-@#-@k%rxVeN0-_lYfoZ*k$uhPz_7-D38f*@yREMXGj3mdSJ_+vDD-p9Y$p$CLkyi}QC&y6z^PbxUe6h)Wxtm-G|N(u;Xbo#|7i!-;X~JYamj%Pc~| za#${g8^)co!m;Uk7-4H4@YO5#2%=Th^G^a3YW-cCkxEhgsEQUy&ykRsT%#qI7P1kg z4EVqSCAEE;=ZJ7)%JUQz-Cg_G7`#|>`~WP9R85O*$GhTfZQ9?PTmlDPZWh{7OP@P$ zU@WrGMo&!7*Q=Cb)13)FyEhE|fTO$Bc5LlHVG16pyn?|By)}?kLdyIBfylrBd%?Ws z+`S|+g7>b?hqJe6LU9>Mpv2}q3T5MKyH3g4aI_-dA1pl4r-Z_ZDB;;qo5{!W zAi$yd@(b#`Fe6_Pu3WAUn94O3iNi0m&J*`6&8#su^dxH-Bi3FJ4iiAMFqpY78xFD| zbkXs)udJ!A7*flgE!N?Nq_z926edv;%r?z{*lOn3sH-8rCj(fYSn-=Q zWUIw~SUreUQ@W*Ki~3re$PKoVepcRmkti8Gsw>0IV*2%svYH`;=6S8ruQrf*O&iWM zphHAQ!a_FM_0s?ZfllKV*V^UOXoS{utzY(ZS?fu5kzm&Mu58br!=tl-1eH0r=M+gk z6WzS?)P^~ZE#9P(@#b7u+1S8@*B7bm#B%(7{bq{WZ&;*Dso*8Bs@E&Ep3}v9(U59X zdml&z;hw9p&$v{h>=BDk?=#9hqsSyEex{i+wnM~NAQnx(#045qf*<17fD2971%v_s z`MCl`(+#=fjN*k3<_+sv+VlC|)M~~S*LW+^=MC>sc<27!0LS>=z=y#A;9!XF_V0m> zFFK2QB;Eaah}4+7xUZo;@baF9WDnh)xn!IN?ZTgZFp2628sbjHAv`IdKWG9B{*;|e zDm!k&x^aM@dKTDO>L}26cx#ZCPuQvHga*3|DDW~s2~jbL^Uu&zOwd~gJ(3fk)SE)6 zJUZ9_7(o0X(zYRi2{Ej5OvqL;k`KTjx@P~E-Yw`CVb$|@H_7e!AZO(^7JPJtVKI2l zVOBPjuvHgm897Hit+YS$I}%t>FRkbdJ5VplATsmKQzT5n;*6n*s7G=Z@F!;(lttDu zT8M^>00lV#OUZgMy}06!gi;Yr0G3Hb#a`qP(0l2=DRJyR!y^@S%_^{%imO0QlK29s zxQSyrSOvOIR5xwzOX1C|TL{2&;mzDjz)+nb;8&C8UtL6LS`qEkOp5{DA;mjresa19 z=y>kVlRolFs=Odx6P?;xXf(IJdeWnC6(bK3^eWNqZ1tQbaPJTeo!V|rt-62fG|bQq zq$9WEwRiujXD98@C#~Y@s$o!J^#9PcfS?*-J_Z@(Bcu*Mr~{VNBCWaLO!_aC505|x zr%Kf_3s(NtDR_3yzT~W|wvV`9kW-w$#Ut^%)@VP+$lT7}f_1h>Gy;GUL@&V8G5F() zJ89n4h?zDDM!a?wiZ>0#7q~!;rvyF3Zg6%*+i3i_&ul<3go{A>!I-u5n)!j>zhOeP zgZN5^QI*d)s50+oFRlR;0>8nslYS3LMmiNi^}^S>;(G1+{QCasNJ%d8beVu=0v|ac z;3inGK1^0~DdtAfM>z;gM78YpWNZQf2~(vKB7q+Ex01YBK59pupqKi#J3&W>y=qo= zb)8xZcPA|f*GN6B8Vh?On^^V17Z!erM{U)q0rspLx z@AU7W`xtDbfiz{_$`T8c>C7&DLyGZKv!ZIpFO}l8b9_~kJ<<^9-(Di<+CDX^&w%Cr z0BVG?Tm=9j`UIa4!~IXJf3hk7vnT-%)cOsb{$ynmm@1{DTSW0JpY_=0|G1XSJjn)m zC?UPu?~g2;fVC>fyisl+P|&(qZt%83`t_8o^HV)hGRI4M?Wu;6&5iaXT?Odew~VuY zxcixW0|(l|4^AFX7+l*9_}Ph-bOOs9=umuilo$R8^$emGhRX47)a1DwFv-s8@^=Ry6_-cso0s(-Jo1ezEbjH=49cQI3JAT< zo)^IP5qB8G!Or-kycL1w7FEWSuZ->|y9e^Su)5*#5mR6ky)8L`HeEadETX{DnUEg+U}1H=(f=ul{M7{FYLyk82vbHkDMAtMCm2}0x|HEIHoZC^u@HLMcsNRQbB|L0V2{V^rK{lqg9zHOb?Rrx^zMN*&0VIXZ1s3#)r+63I4%Fj zadwO2IWnsC+rwY`*0|4)!SNdkc;QEo z+Pi4YA$#f;l%-!_Dm|Zooz43qWiKlqcE=fgphXw68*=?NLV-pPvpb--I~1|pd8ePE z+Q+tCjo@`fZtfY>dl~xX#*xK6(;qcNBaX1&{IaL8ckJov+@J%Jgu=vtRgxdwAVidz zEkU|2L!61TB5XrwIwiXwXDS6}3e~Pa%zg-a1XV7YdTACMksnz^K6&mMh8&NA9Bnb4 zS6GQCpfv?1m`l81cb@a`{3uc?yQhOW&DDbL%J56Yxg!de zA9x&gUuN7IE-WgAXi1=<5w%v~ZZ^1fzd-C(J`|Q68#}yVjN|!&Lw@QoYgFxt?0$*( zRkMHU;%qnN7Bl*DdDAJrz3Xd}j>>Gam6;KoD(b%%& z_0p#DRBDQ;RH-KvPi6())MB=v5(5i)Y=vobg~}{;04^M!A_%B43JhscL2`5mWig0p zykffCxB+QJaFa1kw#4uN93vnmmjuHj2+3teWWlDFZV9Gmis`9JWC32QaK)DVD%Gkv zL6Uc1j7B<~6szfg=8)*Z@Ngvx_7Tp<6HaykH7fQ})~IO4dhC()X75jFfuWIH8#_jg z(<%Zg_{#5wTufJ68)||b`XAipROK~m8#|ex?FdMSpZgx9xP{jplR@%0(IFx5uyO-X<9IB#_!(yL?cTZf zH~o)?zWY#L+c?K70dGJ|O%47~hdbhd?0uz}eJ0@dL=Abt*ub%3v{)i1eaZ~*k)$^S z5@>zw3b8p0f2%RWMo1}_YLLxV7--162b><{~8Gr&)L)YmscGJIWhs9Pyo5*X{|iciDi(?nY3(`Xe&L> zHQc-v0;3H?IQf!ASQ@NB&WMU|-(K5N&on2gz$h0V% zLoDnHB-RRKJA_W6d@!AaS|Yj9syV0wYK_c2+eG79&LMLL`s!_q_HCYE>EHY}d`ZnT z4wZIo?4`XU)*?&gLKzlARuD%-CFwIr=8 zg^W=xoaD{9p}(LTlKt5m&FFZ=S0Uqvf8dyH+zKo_OfjrHP-BRs>-m{!@@l zJ&KA+K^4c;oJt9y|5U|=RHbW5Ii4(esg>Mw3t+a=i$iVk+S@q$s@l_k5>2lOzeQY_ zope|gt1)16rwiE7-}3< znUhkypv8d`4eJPoe&0PMMV?R+cg&XWOtW#HIFVyctYRu9233g+P+n-XsLnKzrt^v1`?=Wi;teb~`h^fY35|JUe zMP-MzlNf%5=_F}TJCb(h6 zhEfcDMV)4Sy#8>X!Y)|Q4R?FkGhRWL&3lK>`etI+@4uJqMpf@i(h1_(vp`X;aNwFo zXeSm}N~5+F7dT09h_z$~X%Cj3vb~7y7%LUo)l&^oE1XjzmgFW-O7V#8KapJ-AF!i4 z*vG=jA$QpjWi4^fus{E0ABl8UBr0NW;Wv>Ak)g-A4o@Z8nn<`tosCoN7w3eV%P5ag z=R2h*$<%V+m`;JaE?p1gqC0Z*ZlTDQaS8P(k#%c~k#RcfB+$ws`8(eD5cpGp$MV2J zb%>kBd&mO}+|CqI$GtG;B48CS$&?`3pifcVMp>#34xdX8OLIULEIY9d#ZRW0MJ5jUiI6g2-6)h_^mUt!hlJFn700 zQtVooOTM#TUYu(V!=~TZkBO#4OP_;BW@NO1P%atEqp?#^VE`BwNH6fZNi^LDiZ~&2 z=L|zi^#L2C+Y&{x8f(b3vegQL9z9hsl>&YErZj~F;f$iw*MEshszK;%<*?jW1qShB zm#BGD>{_EMYtsxp_G507o5J`&U_=+|3vhl{n&5SFgCV%2!+W6TMgwl;SAAF2)3a6~h`R%)fYvaCL)L$O>*p=?Q6!dsAkoK9u!>}J( z;QW`p?3ayIR&^_h?nR`m#zU!?aHB&f>wv6>w-6=f=VAxmnS_%iZp_v_ba{GR6!)%E z=YhBfc=n`TZ61Q0}!~6gnCdPGxLEjA3T_d|jd#zo_aYFtyAY}4!p`IQvo7Bv#I^n zsy$7UR0t;jqw7w@5cG#V5>tMrz97LvANN5p{wYu@15~Yc+a7x&giAxOE6IxztavVG zvx7zCM)i$Fw+_`hG5=-DbLGes)mm0C&W%PZBC`dKMeq6$?9XE4)#3R3>K4^Ws@;8I zB?kSo-H>~;1RU(@t0UrMUO zv2cTuv1}Crw>5;iH3f_bF`Un_u+yp~+hoqiqO~*Dq*J-tloN1wA7OSPl+!gW$#WM~ zp^DujE?idM@clfOp&(UF1H9NVG;J33Xhu5QJL2y_zK8hLOkNwq$$^v8h1IiPiB7}WxfoolQt;H#j zT)d5LiM~t%*>JFgW|r<7qo%#aIzG;qNWD(;hv}b2p?KWykL-|ac&wm!u_5e%?LS#& zYb??C=|1Fy{&unmXs40JO82_Z3usrxKk` z#7W(!b3l@Ze6oHQel=On8{ zs2vzJBaVgeHD(Kq6AI=}yC)sq2>uRe$c6H=J0S&%vk6Pcl49uZxq_ol0smmwcYLk~^!-l9dyCa^+;q{!*M`sED$Y zGeu6TvMqHFOc-;9fli8h_x)EZ#5@P!XTDO9)+4I%!38YWp_1B&nuqW{V z?U?CsGFvt@Ip-Bs*vFdAa%2jWS%J|e!vwaaZ*Xa~%dJ#tQfQEh)xkce+P2NG$^I8< z?-*QbxMht7JGPzd*vX1_Y}>YNYbQIlZQHhOn>)6hd^z2xZg-!1yT7iwRqv`=>*so( zXU;J>hSBHf;|oZhO}+dLV+n`ibL!$4$gK%R=KhGvD$mn??J*DuS*Kcg3F&S5UJD)X zONAzH_}Q)EP6OdrvK+PGr0X-*|+DC1{00WT4Ymges{M2;!*Yksy~5uhRM_Grm9a)ps6VNF z{Oot?Qz$xs`d7o{hIIVh&yCfFbo?UEm5+_8d)3dK6JFSMkRQno&ux1@&aK@tIzj1c zpLVPtdENuPfxb)#PU6L*%ab&=Vv4LG81iWw2O=0Ts>2TO>2<&s)e~)%;}~#1Y04~C zYtOYiRx7v9(NBh&sWxNw+ZVA4y+%I44@W`PFt2=fSCH7D4Cee4JYhMNU;IMLcBg5G z%@C70;PN{4OxlDbhG)!r&+!iAPMr){thGAR@inaz?p`B$Ez7i>j02wo*L&&OID7>C zs`wk(b!yJshW&&ep|ERYbLrn;>dvc2>ZTb|UU3rYef6TA=+k*i=QWgv1tiK(8(Px} zJyVP80O2cZDhKsuZpJrcvAY=&4YOhWuCzh+jHKyEsucO;9F)r!Iu!kg*D%R)R6GG1 zlCmo0Ub`z$3BxK*&Kw%B`=7$f{ViRjw88QO9_VW%W*dJeGQ0T`pV43Q2jJKsBUmXC zu)!mk>UPAW)GQ-$*Q<`9BWIyQV_U+|%T$g97Kyxr3MA0WtUesWts?vU_X_LI7dYXZ zS?eap{%%#|-GxG#&Ogm2Eeg8MJG*RvQs@*zF38$j0bzRsD5nFth!I3EUs#E`<@4EN zt>qtDLanGdr9%|W`#w>k`WCWFOy9I4?pcL$xF<#Et;fCclfhp^=oe{up>R5ffClUl zQL+E%7cl%V!4cFiWq?h>A%;H_xjKQUoAm@IN9I&SGEX?ouy9yCR=yvr5I-fIB@q^m zM|HN1Lsl8aj3l8B0@;V8V3o+3qX-lh!OGA}=-0?supt2tv-s6cVkSPYi-R_>n=?B<^9i_C!;lhnc0^9_FXzt8 zuM_dfH7Crrng1Z*l!YB10~9ZBa<0pRRZ5yKCm94W>&{!nD3{W5Akutt*ydKfZ^g%0 zRCvn)-G6lhb#fvh!U{zWT|<26J;itBsM5$k)@m-4FWx;|S>VFMYxgVL(Mr>$secm6 z-tE?L>R!udDmClMV@mye6^kh*t3Ici0S6pYv{%j${&Y`^g6Xi|Xx}WwcA+2HkkE<& zy*E$<)QT9utvF`PM_ytFO?Vl~36t7r7+fR)EH?)rs` zhqzPi#ywV|j-w&V@l&IX(2QU+%Bp+e5a|TIU9=#XlY0*>Fvz5%6I0uaN2L14ilnQ8 z*sm7TiU8dGU&n?OL4HF}az+`Dh7s{O8^5r~FnLmJnESQ*5vU^{%qUs;(q}E+mZXAB zbc3%`gf`Bm(L!|1w_9~yrifrAr%f?J_C5Z95x?ZNcR`^YKUi3bMx91Q8DNw_JJHG3 zKj%JF=k^q=dy>bz5|KPSc#zj1AxG`ZTH;|v&hGmBh}J$|fgj+kTK8LjiMt=BGQ}$B zl9;i+JGzY2r)$3pzBWT`?S_7 zW5ZfLz4Pf-S&!60Zf6;8BOM-4zW=+u{osCav?%gLr&b0#Du`)53>z8&)lM3{h`Z?# z_2Cg^!!7FS1n&~c$YiiztDT9~kdCz+IV|Z{gLfW0M)eN7eDvIL$z_@_qnjz=({e86 zZg<^IB+ex2%v#R)b{9$Q0pq8+v(k6|S!8zY1|Ou9RDM>h_lEBw$}CRTyp6#aQ|apq zRj7~9DGJX$OycU}+D;pWGTak6E>BX`BlaMHX{!Y{ACW0%s`V#!qj86+Dj0r$*e=N) zRLg1uvKgDLU-J3Qa_D01IbfH>1uKY@E5k#Z>C1W03!$SRnxFg6`2qVWbBheaHU#0| zJG_}mGH1$Hn?YBGq3`#<3e3vaoSwzY{G(l(q6<6Z3YjsCjt3w9$%aj8@xD^6)iq;> zh8+#Dx=1x*Ph#}6y>G|b9!FxtnORJ7{O6u<5t~`NHGRn_d%M&N-C@vvOX8)ya|L1E*dgLpBpo zPra-g%nHWGUXFdJ^lo8dU=6-FF`n?OGh&AI6eY7ZSdaVhLzmu-# zX}>V$E1oHaucD(&c@?}SfL~c)1)2_qkeqCt$}ulAn#Ab2jEO~v;$1k2{W0P)$igqj zJXRXLR9X2^tMafSpH|N9U_^E4Jj76l zZ|~_VV$2{Zu{I4iMcKatzp4q^#VI{`Z{gdqD5~sX+LbG7`LISh7(b1(96t2%hu;e@ z9Y!(VOsxh?iTSi{rjHRb9-1OdCwtX9OHIIrY%mg9|7=pS_h6DS+k)<%K<#sC>+tn^!u&}v-J zd8YJ}1>?bXjffjS42z!sFc^j(GHdmU!7q^6Ad`+?5Km(^*M71~U$UNWv$44KwN)uk zWailTJSEt2zuR){y!sT`cKO{m)J4kK0fuB&qucatHE_7I{2r!&JLQVlKVoVv* zI2SED^?00Pbk2pv%mz+u+!_u73BYU*2}*K~62KPs7fAiMOjVfEKwhpGBOyg)nay0Y z7^&bcpCUzU1+@rP5oU_Tom;GFSF?wFADd~KD%%iJTi};ryf#<8dzD<>K%M=~iGQ8ls*MC|Y~%?1w&7_WTU4&s(LNIDWkeaT z^=FN;gl?D?Gvg`*q6S0jHM9L$%Va!wp+qx-BkdFnGI{FS69zY;%F9M6TtO&JrAI?7?@{l+Qt`71 z61|151*g!%kuuY{JXEtrT24sDh0AQ%Y|w&@PMs+7 z`EDK#?s@+AHY%zmQ|!40McgQ zxs-kjB9`PVI1g0`E_*MdKkFK&qKp6OW^gpMI&ZJX-l2)$To>{+zSmrj56aUX(A}t5 zZ!fNyvl_$2tLl-04W#C2k&S#KD^le5Qk`4y8^s)^tJpwZY=HF+Ft*`u!HrAU`9B~M zi#%Kbg5W&Hd-Kl`?Jdv|!c{Z|R~oj1l{)F?f}R)f!`e1eiQLH!n@zFsW!msT@>Pmq z?-_G@M_`S_j99^0T|ZkIw(%HE@J4)sl^^f&lqaf~e^5v}(ORz?C2U<3nR)x`EbiG>BaYO6q0QDgtF zTuuY z+$5x)&3ICjiwSUXL!rcBceL+We%ov}5YK`xRf51JAr~6`2XreMXy9Fwd0YaEI*po( zp>oW7gO&+;`>#P^Zs4s%2_+!~efk7+zYlht-)sGN8E&|}ctxpOGt3Tzm+GDwsZ&y0ZiuJ@3sY{XaXZV+9Z-PRz zcZ$zBIrnFEhM!WOM1~#Bqr88GbOUZ2-~9`e#u1~-!*Jx1ab+1R79dIPB;Ut+bW@)# z7t?5-fm+VLMw(L}Mo#MzfB72j(Z18ZLD`@%qshQqch}c-M|HE^AXuDJLI&kiv3wc& z;w}BY*t|KWv-C`H+8(NwerNg=2KZ@*E0u**g@{TUtll-NbCs4O^~LX-gbDNGVw)&NmdE>2gU=q5!OBXDpa zPFAnOn*7HEV5$l=EUHa;J7_5p`)tNZjSh3Ao@J(#n(u(9U`mCoLhkg6t`*NkV7qmx05IlSud4Ji-wvRX}B@hdA7jMVLoxLnA6HQ z9V4Mg7yp8b75oR_?V=fq?&+#9-z}`Kl&Vnq%_g$TdZeVTHzuI|cOYyZsH}h5nPL&( zTAD!!tZp@uSfo|RY&QykBy}cfU4<^Ts@5XrtEGuWz;ei>TrT(Db2aa!#%ZfWWQsjO8xkinR@0E*7X{$yHgt@u5Kriv1B?qR^48j! z*zbpsG)Hcnu}*{7QtL#p-N9VC`85yzjEj_etnM8oI%hN`J_TbQjN!QgW|x$Iv{$Kc@>&C6ov;T3S# zQli#sDs--2xV4X2pP~pen+39I-o$uJTY1E7<_5e50ABAW!p`XU>5fwK1zL2MtpSCW z#m7I^Aj}GkzLuel>l~W>N^0c^rAJ;GW-H>hb{J%>6aPlJTI5@35t-i#dnjq-w=3OK45$r%sHYk zX%nLJdb1p1pZR+8J&|DX(j7O}nM(94m)0E2GfjOb(E|46Zw|t;%m}6fz2b7r`0Sy& z>#n4{W(l7IYCETR1nU(@os0;w zN;_Xdw#>&q@eSDO#0Aa6d@FPks|TB_8Y*=aY7Cg9XjVV?@^u?y>A`fx`Qm8*5iL0a zSkuq49mk@iMZ$x9(p3)oz_@mo?BT`xc_8TwehmD|C1k(UV1 zS>o{OFUCeCBS%T$V&PA`Mzp;|a!M~l%fQN_@UWoLi)3s0vJyprs^Xk#J~&G*-lP|Y|hS&DzMz`W`$(1;ldd}2vW^}9dMr)&kUvK#?y z&nUH2f?mkw5{J;twHAX(H>x%z23~nKMw~(URSIj{5F+U*hUTWW)dA1#i1;)DNL4*j zKkVSp4Y8_(V5;JzxiU{fex@6Tf0nD2qpLUMu$lhQmcay5F8FK76Br3f~ED!7$RdbJ$pTF^-<$RmFH;x#oH zr|X8!25P>+L6mJi0G!4U>p?l}A*Jg3vHON=wctgK8>Zgn$mF%S#aeZH52lC(Wiu)! zmzAhD^f`Ok441sOgv)cF{%?;%x!1}rF~R8d3%Yw*w@KBRYfeQyg->(*w$u?;#-2TT z=DuqdHZ+9OoO_$upiLQ%P~v&d!SSwoip@f}hfoc=Jnbt>6ovZivazr(d9(TK;;Bp3 z?ZepKSpH%YsbePROVv~vL{+_AMjyxHx-dvP^NlvULrM~v-6-bAcX|Ow9(AC%(L1VD%zRxKUvB4UrX=8*2On^*x8k|T*3VbPvI=)Tp2^epCH}jk@VR; zipBQKkw!snhZ&EL%{ zr*)5?3U7{%>}#4^`eX zFx^sc<}VSt=^Y!ca6z{y%;|iD;n63sTMn7A;gORcTYcdP4M}f5U08<&*a%D*q2726exS-4fkECcgJvhWHo5YZ# zthN9VfW9@0<{G#)5hZ2|o;Knt#N#Q9Sy&O>N?^NzZXJBkY(7!coYM7$U5aaQ5x?{~ z^;9w`WDI9Z{&*-pm^*>+z`jd%tCM3&Wq^JMGc}3=c%hdr9^|!UuJuvk`|4|0%sC8R zNOCDFazWtxpbBsF-S3Oi``FfLasRA|=kX1}f?aceX4u}|k@oFVxK#unnAY1rqEYW2 zK`&~oIClKYuT9#AMLXH!;T|HcD3&V^KU(b8{h~&jtr94%>qT`-PvwLi)65h=yS4We z!!}xcNUXtsqR;e@gM8fp1~WC%*jH1TNi*&iiZ+pGYUGR$PNR}nE(f!#DIb)S5oMBg zNtC0S9Y3u&{6Tj^=T4vkKDUw4Fx{nJSHVpyO}|H}tUxjxQsHz9HhB|%TQhV$B7ezE zB>Mby7vL@R#gpsWO(Z+6dQf1q3wxR?`?{jYvV;EtOH6WN?1P)c(S@;_{EMP^WrH?$ z-l3^RY-)7;mg>D5^uKZn`D7z0kbg_x)qH=*{`<;>u-iWf=*(?x{=Ik+7}F^M%8wd2 z9VyOQHT#|lsbX<}(4vPUjRHpz9ysgdAMd;(wQ^3wgmcqa5rE3`J2TOicuN}$3?`lP zDdXi*|FFx4Mh7TEuU{Bg5y*MwAe9 zGAU=P_C_bd7UW=8S8_mFwShZ(c4T2I`hG}eQ8nlkQpV8hI!zIZF%;*gFTx3OMrwmf zfcru=0@6lqRyrTNQquY}w`a=iN>INgC}g@?(D)H_IY`-te3Mv}<@x=}c+2f)FViul zsfE_&hI2|q&Xo31xB#g1&npeJ>H4)7sUwvC`l@9*T&&!_Ws|R=fPfhOn^*1hE#Tou z&u?gG>ulpBZewCgqM~o*{7+4fL}lx5#W_TuDNLgX>>fhII6e@+g`nSY3HOtHk^tM# z-{>Xtab20l`Y=YB#F^%IvK;f>GpVdhfiAbX^V1*lnU|wc!0Q3`{o>8dp3|2+&7M!w z-PNBUfZ+aLL}v4di?dPiL0R5DBXG%{V1`W1wwiIdhD$fN?9($zQpScM3_^EWx4-s| z=W@>6Ad)ew0&uA3>>~rUetO%CI_nfkgQWv5NhU>hoXXtA1rhoSQAp;YjL4B&Dsp8- zVO2570(Ajn2xB5Y&B(Xe-s_AJx{ADdceNpSynUK?$v&~yM9yrh(J>|zVXB1@Wt92EsS>`^ z=~`}>qvO?{U`4B{4$opOqQlV-N$09W19?%hzrQ!qS%wx~>!Q#qkRuzqN*PU$C9^<3 z)rL_5bK@_T&S+4Srp`E6YeoTbdk~L#*EDq59Cc##-`pVJuqQ@Le{G7~Y3KV`?AtC- zx#*~Q@YdBpP3tGWhY`ki(3J}m>*{585W!%w$Vrmng@rigkx7Z&bauP6DRD@VQ1SNd ze{!v1Jh+8+Xi28gzENe4#ZBgo#7j4yxIKy#Ce(l63D=iF>D#l7dy9@X4wlex{B;_8 zCx8?36LJfMO3!z@{k#1ugr)&3BnsuMiPTF0(`1aA|pDtE3GChTdSkK{0t)MUo(G>2`Xs2I$YV* zB!3Eu({b%c3*IavduU2GEWLz3AGQZl6%s18pCYZ`4Q*Ro(5@dp>c> zT!JlUsB)mcTI)@r9N;g^upxWvh~!N0g}F1ey*$AlAadQb7A^CiS>}>(o;~2#n;&fq zhBeO#!t*VUVVUs+yqhR`IF$`y=K4g-SvJonU;4iKh$#HXHVpsN)>|p6MTud|yEH_` zMg=X%32#(qkbrIzNJmpFNHK3T1jm+My8-jAFL=eW*0)PX@%=3=Mb=>G^ci_cd>=PM z0IeEre*xJ~5*=`RVHiO`D15sqm&Mb^jl9KK==IDvaZTwRJW6PXC4ZlrTt~pqd#NaL zch6<5ho~FZ)Qt_&)klXom9=XL9aHL=1)}7KohwBn^B%ReeR_?zyBCQlQjNW!S4QId z$JSD1dp5h2I#UG)IM~-5sACo6ng)>@*f~cGkK(}+bmlma@7|;#2}EQtSaVU&Nc(EY#M*uTR@qLQW} zswnDbns$mYCLQ4xAF;e@=HPeZIfcBp%^`F3X8iR^V>jM4f_a<$@RG;GC2bD-P z6s(kWm#@I?2&KL>*cW`lGk=tEm2q`8zWvqlfzo5xQO6MAADH(?KLVhn)NtT@<;-0P zf`5xgfBKrWdIfz^>GGkRyWdk`bqTo*h~SFLWtPQ+wkb5u50Hmx`ksPad#DiZL8XwVeeWF%H@I3 z;t%-u5#bB-^MNt6Dy`RRcHGHrTBuQru_1gio)$lQzScUM02Auwn8@T1i&pav zM~Pn6?uI?`{9&VFIIL^FNNRq;i!?;DUAn#-J+aFfC`(2^9)zoXG>JHpiVl;OKK3R=k|{ipVTyX;mXT;fK~lP(8l<3c zOKgBpS5Y-b)+gm*Y)HF~=!x}7=L}UrhrtM^P=}gqVXD=b9L;d1G*YFbe=eL2RW<}I z{^(y`U79p&@s?%TB6Q`{UmZ{v=NlQ*>(&9Dpx9Y9;AQotE}f=Cs7P#i(wLs&XBQxY{nlJdA_D7 zlZjquMv^7b(2#33^~rs9cfmd_RE?~UxY)J@;+Va;-@5fPW8L|bZRYKu-T~W z8b4|oaGrDJdmeg|)rOZp;;$i#{MncxBDS{#TIKAJUeO=Un2}`zb9RrIS>g^u8x($p zP-vM9wvW8oPRQ{dA=2i>%v;dSkk*}ZB`F;)%y?{HbVKdn&dih+eB=x9mKZ^(WR5G2 zF?4y1vHY}yVLIpJsbGrw+zD0Gf)o^gA`-epuwvs zIp*{TRqTU**U>Z2fqaf@T>t?<;uET3t|N%x2ASy#?m5^Ca@w1YGCz0!0#))JHqmdNcbZRKjEgjprFQ zq^e^*8`d?-U`{wEy(>A5s*Oj~F&Ntjxi77INx2CvfO8sP)Oz%5Y99oYt?L>@o><>?nX&4PKHuiH-ULC3WHCXuw7%!WAiHSn;s*9braq)^bu zv z8Q;k!RuQ&=YL$64(FC#aX#-5eHEilLN%HiQ09lMqV4NPVpiB7ymPeB{T1g$Xt!EZ% z9$t=BZXS-zwPQHZmIVhK-a?||H&NONoLgU)b3)p~^+Qm2*&)>YZD<#E__@OFaobPd zY^rX;a_#B*76I1{FSryjZVMLVY=>Q@}Dh2-A)Mu|$7_kUNu!Uigr{ZGOMV`kq{)9Fr= zbYsuPJTl?EHEL244$C#tfAjbqdYhlNVZ-j?fU}{F;=QYkpRYMBLoBk-?XL?S9YM+7 zXfzC5`VM8S`;IcENxR8q5f85&pnZwQpY0ynRg&fR`nQ^mxv8@o~P9-xV1Py#w z%?@LMF86^eCs>K&I4a)B6}kr#L{Sph);EF)XBLHW=IwKCQ2a_pNr5t7xWSq2iDm@y zgi-9ni)4PZWtq(?ZRFLHgUBli`y$M&{+bE=kwXF66$V^I0-_TEDnkI(f(A;1-_j;L zsDI#i=c^wyWQ^_N8yO_HKg8Q2JdR8|eS?MA&9v!kN=JzOK@o_pYnZ-7nCBz8kCYYA z2FsfpK~+cpFRgCP`n>XH5FntiZ}M{b|GP&Kw6(T2ce4I}+TM{$n==0pO)sLgrVIxY zLcD=MD*!V>`=Zs$fs&}VFo4prW7(9^JHC|K%#6Dx>k0@Z6M@6v`Hf)AwXRZ9NQJ>< zdid^jlDq%Yd^G@-!om zCTPT@VOMAMI!#Zn5H?kWCS#bQf2RtN2?*8l3C0})Wc3NdptRhlJNJuC>%f5cU@{g& z(xvm2X$RGA$WUHoa8(r23yITdw)mGkWp80siN?@EU)>PPn)Xyxy_RWDkmuupk91qdIuQ4=$gV}!7%6qg;4?TIL*w_;=$(6x1wM$>=kGGl8aTX zTd(pW%5FoxbEQ0ehR?<}NOMUE_l9f6Whm8OSwYm+qr^faB@RnPdG~O91VN-CzO+;( zd1?K?-P3Mu^Ayb~r3z*^9<#wbaqxcWHn^CKA{LZ62K2~7b3t?{j+tryM@^$TamF}r zN8Mf?7D7{VS=Pjlky)EY+?Zipar8+R_YbUhtkP)hUX|#bmnP?2D4}{!SX54M?DrY4 zgb(_eA2!W?&>?IeK}TJB&p323DO`OlIqBMMpiV6iX1L*#kT|YsTd+@Nn}aBA#>e-l z<7$Hg^#2uAZEmL8JHBmT>{_i&MtuSrmZ1|7r3CX{q?0@`L(6=%DXL4VtboTFt zk+7vksY160CeObfRsQFl6 zs)7Yx*V;*fEH)Hd2lx@LuMCFPUOQ9MNc0cO2>P~+pqaW#H=zQpvZn}m!LjVn3m z-Wacaur*X~;ZQX~BZ8(F_)-)eTTX=r_cZ}4zi_0r&jlaRI15_-8r+M8>`$H$0%V8>7CIr@hirCe3k6agtUN=G# z#%^wQAkrLFW$Ulj@ep~dHD?m4+;6EWadz^fX9d)4RbxhTQRIUz^*YGCbmZ7U5&2q| zS2sN{%bAlUr5*!sD=*z=1@}js!&`9>-tbxWUdr^PX&*{rNOr_yKg2N?RVD#x7oHfU zc^2SRE7yJXQ7*<=2*3k%v<<6DYXkOw2we>bl^iT3u&hD0+~}l~6P-csV5v9FU!kTx z%d*f|**@y^RMhD3`YTaw3<;w+_2D**Q`pfDM?sZQ@VqbTR(7i7dkOp7E9OyFc$UeM zjdhQ)L`ya5YZpA_eL*hcE_rsVGcR>C#~u_a9JlE`$hS|}Khqp3@`;pV zQJVQtHcwsa43W0!FL3|MG-j^tJtRs`Fx}9-ZA8B}W`4_-fKjaFD%ar%*$9r#vh;@K zX!wi_{!{D#DAxconeV?yTcjfJp$dH`hy;-TKds|GmA(pLQ)P4z8!92(y zbCG<_&8C4K;PtUhkxZh~+I(wZNvwhQ z8#Oku{2?;IP0+&qGd?pTKaHb<=OGf0uzi!Kzq8tz3(#R&;Qz8OXt&oZR7srh3JDtC!{?<;^h`c?JSja2~ofPBGlvqTcVc+5aCF)Ur|ar%ZkYZ3BrI9}d!4snvxwfXwJvDa_wglOLh~Jw7GM@Mlv&Y(ZynLK9bL*vQnIAHLh6 z`vfr(LZ=_=`rJA|BUYFH1{f(dOazLi!AX^blq}H=6M^Gx@LdjpqwT5^ij>GkI9V%9rMr5T7lU{Qy#HZ;0C5Xe6~ayKEzY>obRwV zDNJS=UIl~Jd&S>hW=vYo4V2o1#D*MMMA~dQu0*Z8X76;F%674T8RX^*p5k(+LklkE zN$TZ<{dkVc@@hpS@x?_PEKYQ5x)p0kv5OTCKzwp$@vwFneMm;*RAf~kGIjf2sP{Wk z_PGo^1DzJC9QmS5`Kj1{Zn-@aCrnPaaDZFHNS%*Ke(fw!XOPwM?Xh%$*R>oy?j||f z!90^bJfkfuxZ|;jqnkI%T+wbwGLVTo;z>{B2;Z{Bm8%VdA8!9k9Ji_eMbY$)Vf^1p zPydTJ?msZ=-*d#mf9Okp$8q4$nrp&{@-|^?JxvtlZpq;iD5#1(K&1#g(#^y)n^Oy! zt7PvezCqtn9Kt7%Z^Dg}Ix$UR%yo_9p+nbI#@*!V%Y)|^`EM|;=^W5ZbOqM7naP>% z@$`+G)(w{>>h?Ys*v-4F`w1dJQ###Cer#@ZM%KC-tXrxT7wmdCQR=>HZE~}gs8vhI z3!0a)%1$^X7N^K!5<%7Yw_H6pc@7pcqFTCU%tOY6es&!1V^c9(7)72P?XiRDDX!lz z=-}2`1BJu}R%t!)>#!D1ru6rSYt607v0B)c^`QPn$7OZU~!0FTz5fUV=lv z%m_661D#{^mi%2o`O#5JH4#;I%6!QPOP=88(=T<3DT}=;@cQsL`9@JE;ShV2Jr?dz$x3ST% zSt6-tY8Q1{Q6_V)XzY+ZhroaI zt$pibe79myKhZ;saSIWHB_UnM23gG)ikg`NNCs#F2DG3T%+t1(3}8Ui%O$8yp2;t| z%}mk?;-{QmHwYF_)FlfBRO|>|Yqq$PKc-w=rtx2@yLCT-^^n@xopR>+l0zLw0QdOU z#5S!P>-DS_5Pd4JshUwoCF`)6fd-3wN%~UYo=Lu&%>v?C?>%+KKPx6n4mlnL?K6a< zTwdfatrS5Z*bGv~FD2E%9EOMb+DwkShXFUChCef)TcQL{$sX$+rLu|@> zZXO)~GsX4C#eiZzgFAuRwMc#~R)7&vFf}aGr23C8>rzAA0F~890aAbGR%%Q#D%0Zj zm_f*ccJlt28|MfH6k<%%k>x4 z4WCe#a`JAMAva{9=vy0?PBBPZ+_g2GCzbduC0kfU@t&IjciFN~O+RH&6~4J+^BAb; zcxavE1t+Rg)j^k{Wio}+b4JuH+znPx{Dewpe!|8rn(C6}?TiLe7Gw)@djn~?kr%+p zah(y`s`lK>qO%x8cm77qSyrO3|HV?^Vtf-2E(*&g!;Zd3S36QAGjJtZee8Z5sxYT` z3yZE^Oa5n=-7AnBylYAL7OwxkyZOLP^j3}}8GU(@@qiN4gOE3~DrJD7$SK>iy$Z6J zS^;0=bCvXVZ3vI!9QBFZw7cX--h{U6y8NsEgmUy$)A=m`HP`Q|l>URf4BTQNWZI?h z2%S?g8>@f^;WP@b?Zt1GDQ;@ML&}ge;1gDE-hw3}MxSvKARd&;+z*QtW*$UT*YGR& z?Y>>2C>zJ=cjFvP&D<3LfBL9Bd;dMVn;`1I6q8hcPbh^*|5Yf3G}n$O zAq!a#0)OTT(;M+OSDPJF@~mjbYbh}N4t%C?ATz=!2O`Q(cQ~_(rCR>`l*>A!dFIL> zDO1%~G|=u2|7qrgemG1f7co6nl(QpdrcGAG-y-RLLu(+LQebHo;AvJc4Jpvf>#)q5 z=*Koxa-~>i-?J%8)H!IkGd}r+M=h^7TZJc}*lcDrGc6y;l6;OpcS^r!7l7`!ivlUp zHs{H5V60PI4BBfAA#`Ud%3mb0mAxbtqExp1`iEwC|05M-3K!Ifj;Z#v{Dx7!?^KZS zfAk@Swl*f_ru6@o0Sf-x_kT7;;;p}t6mj?qrjYg^MxlVp3{BV?;Q*CDCnOEBgs?OY z$UNezX}Qp*b=~^1sf1u0BXS7C2Z%Sp{*fXn82c2CRn04QtM9-bI; z^5=mbta*@EIDsAgPT7g|qGlf(>`AeL_+5s6gI1|=tg%?5LFG_vzYuuTAMp&smi+vp zWgTG`a<}~4~vU6wu z9u>-8DYc}~WP4PHU9lS0kp0GpM}Tkxa130n0n(ro9&_n4KD)sf_8opvs|yCy@hj>@ zCZzJFfsQ}pEdsr<&m;LF6M(zqk#hJdeZO4PTUpLb7fn$SW|z0fMIqF9cBmC45oX~8 zAe&!m4fB7!@Pg(71Y(Cuoi`C-6_rZ|)@9T%X6dRS`oi+P@fX}kE;^5-QW4@bw5mR% z56fXuY60|L$2^)m)Lw-{fbLCskst#_yb(2pUJMEI{tLTWYl<0t?JLjf?=pAsE)H;(>U#m}JoM^C> zKnU8mkWEdF$dv;L8f!iS3{O`N(>im&o8`d@h;f3*9?B!4iw|o1YxseMNb4pVd865P7U5#@Mb_NWEzcrLJkbpf!Jg9(da0bpcccGO`i_IL50Tnl&R2pS*O zASuXr?TL5NE9EcGE8KrvUB>ULtARQ=G4c(60^g0i|9KwapI7%^Yk7%ESB@yksNC!C z9#ERd=!%*e{D_uuYgIof)_@`jX=9n8R*}W!?bB`gUE($;O!_IZ?|I{L{270FJw`ip zJQ)WHypg7g+f20{Wx8Iq+dgIce!b%KC^s0UDAfG*!0Ys_twz|WI!SqJTedy>l=ZgE zY1THKzC0FgUatShI(W9HfGiLBS@yF_rwX0w;9?FAY&;Q4N@Z2JBt$aVpt4QJ#wy7M z;3*YIwd#?tLW4Dw!d*o)dfp&kWuqkV#Afk5v+sBq03FFRYadkVs#K5)&1TU^OSYxV zK+O`VP^*-(5l4*-h6pXiC=oY1455xyG{hG3_|U$E(n z7j7|XME!Oss7M|hrL(@;yjGz-Aj)8*WE7i!r~@N0RU<0Q#oR7f-c-EfaM*Kdu#5|< zf`AxwwJKx!umf-P^MhBVHUjOG-IlY-SGrf~@OsRlX>`&zZx4h{Vb(zxY)!wAPiTiR z(sn%`cRwH!|w4D1**HKet@9)$CK7K!r z92RZMemvOouHR&Q%QPHhU~?ci%m&lW-hS$S)s#o-*4TkP9X(``O{SkC!b?gE_UWS3 z>o{`Vspm%hq*q_dLE)Elc=B}yoGQ*M>$M%Uj>VEvyCF;?GA-dM_Uk6i<{qq`;6wVu z=kj9K8lRx9%{CrCyvO%7-XT~6Tl8IV=LtLtBnXs+GKIB`m%9lPhx@_a3LBtp;1F0@pmX>B(!fOEP4-ZGbkd4Ma$49o}Wl$ z5d>oIIJEl*?HT_G^oiG8_VfKVqoYw)aILWT`5a0B+2>myHUU7U&y%N}2q4^jC}|?w zZ3xgEY{(0sgpw4{OujA%U{jQ@q`8S0XjWjTB)ZvPQp(oby(wqJFu(Oe^_rF;7WsoR zg5nx}*d|T9THNm;WGw||`T;71<@))bCc^%KXc%U&@?PK5V4dHn#`(WNG%0-tQ)5S` ze-17EXK2fm*Oe4tK;^x&J!P33WAr?sg~R@VWCTWp>W6Cd%u{{F+U^>^NqJxE5t0+k z!$&~HkuD(5BLq9O3g7L!zQwDv4YY&WbQkm62wefcfKV`p%Ro^?kPOs=8`FLpaU=th zastcmuT6gTAJP$H!Yh7YE|6de2q!N))csHxHu4=M5 zrwv4wDkVmjU&&PIVJcyIk4wLUOy~x1Rt~1G*7EQWA94xu?rvi%F(~S!(XP7k!1Hm~!a0~7b z+#Q0uySuwvf*#!6-90!2cXxLQ?hu^tpR`Q(*VC(~=bsDKx#047YfJ6gwIxCCDhDb- z|0}?PxEymQL)(7?*s273dsLy1gE>Wa(E>}eO5qCHjp0&d*QjX5fTYq!T(tZs)*k}V zbao%SP3)Pjjem(6?;;5J5sq?tE0kj4qOzr|W#FW4@v^kP{G}Mx+g5~z`@AB-tpOaU zbvy9AUhkyzz8IRsd0-24B`Tao1Qwm>@kF7|vNI!ncfihuEqAmtfvv#bV}1e8WuHK>Il|ecK4TpQ_B2 zu5co@SRVLk5&KMeW=SV_UWVnwtWb2zHe6vzd6=azgyzZ<`=)w?hI3gYj(86y(0}>^ zec4YRXLew+S~0}WMiF^0uR=~?axs33!9z8Bg;6oKYJ-}ISYAL||1ewdKA~73k~*bc z$&~C$_rtTTJlvjqfaIH|0>cz$jOAvjq{y{Ajj7Bq^4`gTn<08v#qStd=0cm{Uo$S3 zEc+cD>s2ze*wi@*@~fk_>7F+GOq`cR`zN)RGXy~PazM?yZdMd--)+~ybX+HyVM?@W zfZY;mm5cPSRB8eo5HC(QKV|aMiexxlfy{4A&-6|T`-*$S%0YUA4AY`y{jP2?+nn*+ zP_MaH7|bdzlEUK=BMe$9g(&95I@vDtA+ob=%#WJJP|YK5M?BGq#pxF!Qf`)PQrr=V z%ZG}KG9zL#lKzP{dIe;7)CMg)RZFS!^+snh=yaki>2;OVW9i>7WJ^4Jl3Y!Vj2GGK z+^P)+C`|?^5(UY>U+f9>7vKf)oppVFhyI_@=kS!{EEp7hWDN0L!VEXubwq$Xk{MQ?Vy=qUcxIU4nC>15 zWOStqfvBk?L6=Mkp5EU)p=x82P??7@;}BxS{SAN6T|iyJZtNaTGy&*@4dpFOk+Huo zG!8NX8FfUcyI~=q?cyUmypT!y zU(z;HrCY*_nH%W{RI5K`jd}zy74op}z*2izO@TP$sH1W2KX`W*IkFW#nH=(Y z7l$0xZ`k(JPX2Pd)pG`q=(3FdtvVOQUfR0fI!5@9cm2~rcxr-0orB&q0mLCo{Fm>l zY-(qs;$&#&Z1|Un=wDx$Ow`WU-UM{({I4x>m5S~ka+%LqdzF3-S?UR0;bQ|`FFZs5 zdZiIYJp7;$>9u9M?r8k?wKF?OpIgf7yf3V{*>8%2JaYkv^H`<{=jY>@-jl8M?gxi8 zH3DFtiT8#Of#%7&YUOjP19ddzWfwGVs>AVQod%yH*_FVe31k-u^f^P7lJtiYNa9y|7qlkARj(x_8C| zi^-OLNM;ah{?{NA7ox%KIhy1$mVUI6_3E}78W9~e_VD($161~CdVw}m5G_ai3KPp_ z?Y(cSUp0RhWeZ#pQNEWFbgW0T|FmtXEviFEeM` zjgl<-NV)pvm#n=-H#SuwFw#AjdTnpK`i;4ym1&_C*jrSDr>x7p(erCu+=pm7)NFCv z+9v4Qc%Xv~HmNeowd>&)7DjdaR~stZ55J_emx34E%ULH4F8w0&02!817SxET-kFa=w#Vcokq7?aa9va0}$SA{Dt&bWH&Hb4Rod`)4G`-wXE4D&tLzk`u+o{ z>S(qo4Ny~l0^+3g|DPZQilP4&YhPR~Z9t{nUy;_R>TQoE{_)+GfPaWD{iBhE1hE1{ zX5XGiQ_&!=5v-&MfmA+GKu`le!{p$h?x`Jq565xW8+27-Xt>lHXm?T7{9Ky2?)D=w z_s03=8Hk4ZTF>(`)kO%(0Npasd`GU+hxvrmz&zE?!ME6o^7kJfGheQFw>~iza>QZ>1=Y2fo7nUvn3`O7DJtC7`78#CvY02dRM^$f`#MBP3)(zPEkh`fl3J zeYT4&hRy8y+fFZ4B0M$u;L|7bmfHaolh^_G9D0wUbJK}KsWrNrz6R3Cwny+oY`J+)+1M?=jFj2R>CfysIJRYhKFTlQ51L)YEZOo*dEP)52vQ0^SkbwLYtodqQW2VXe`JAHPwpJF$vq_^@& zDsxaC&=U>jy?JwP76wA(3=dVORYYaf5T@vy#|@tT^cY|%xQ?5Q#4 zjP+@5#v7 zw2UQ8Fw`^=eJPX@7y?j+5eQY8ohSrBu zT8|h+_dIdE&oJhR3nI)jK8rGJj5N6UoAFDgCCPjRdnqt=Vp4==zB)Q>!ieo7i^>sZ zg5OhuNGzFwK9td0&7Hc`&5LeUMWy079S>|{rFZv>w%s1?6ygap5a~~P7xF%?%iY7{ zY_p%1qrj;~{boDu9rkNjf4DPUhw{o5-UDA;U|Yl;*;Y%uZPp8M32pu5$okln?jVP= z748Ma+;79LUf1u%vB1>PIpR)DI(fhrcaH2OZIh6ic$@4xu{h}kyZZxf2|;9j=#WRi z%=^D6B5d?58-hT2vK&;Q3;e%;`tRxS{Et+KZw~XhaX2JEO;Av1Ex!`i*r;4gh>08n zF_t3s(YOtNwEN<$t)Be3&s_=aOMV#gwlL1+XKMfiF*wIc7LW5mw)15c52#LW29d_w zdYIHeSAnzTp11DB&M}OwroQgFf*Aklro9T;l{$3@bJfy&t>L5tIWphIk00hJ!Ebes zn?yChga^MMd*OHyN|P6q0FIrCGzF2;KHmU7tofv@6|U87H8cgI{ZtG}63q!lI5JNa z@OEHG+G{R4iFJ#xzPx(x<@^W~IdwQ=%&MaT)C}S2Nxn9^rM~?XQ%n; zgDye1oq>1fX8e8py=oMan4|ow>YB{__o~2pV-NM}%mST~1|Xb4kG(S38)8|%(~@a0wb5HfP8f0NLF;$)n-mqwjYNaB*^GP3+I}7@I-ESkYW%(ek2hw&4#Rs) z_KHS1>+zY|o83{UsAWE$z=-vv4jgdz`}B;p;mH?C4Oh_>`W78)=PR_5#1yU581~{) zZzq?nIf=CBA|5WedXlK6qpazMROT#q^i(px^b0CRDHBhUPB}cgk0$Ktln?kezJ$k9 zCM+^@%_(BJerf%kIHVxkU|zg_6Sqi}hq$V*qK3#H7RCvH6;FJLogd@FJ%O=IuXp$* zf)q@Go6Qyj+*e{a7`X4MWfU|y5=BGXL***w6E5R2B}ie>{c=yj`F*S$y$hVVX(G!S zFpX@<)MhkIGQVa+dZmon54xgwuC2lsBT^$k9>GL5so%DVF8FER{-wZIiIm1m2Nn2* zppTsQzxlwGEzRu=U0j_^m0dtT&i`EJXDPPZ{rS509x>Jo_Wbr>5OsG+NQ(p|$l_v) zz-HjdY+4;SHUamXn`sl{l|`@0=@LQ`=ssYC!A|ZSh*YfTJcph4nJUOVFZW4xKNuK$XfqXnY{}-@Uo5tBs+H>Hk*!|2?Yx zwdhyQ4gL;`S%r=Qg_4qAO_Hyq04|VUmaZ@dvsJv72e_D=-=Krze+gkF#wC0O|4p@* z)ufbXOJv2KwX))Uu+CzBaUPSi)%ihVzzdb>j%?aG57`kIhu=Ad4>E``j~gPq=6FRD+@`7LqGDGgO<2RGwtJ zRfjhutQr-O$9Wa2>7`ZkAjt{Bi$sA#Pv1($5Vz5RXxMcQt5iDt$=`|I(uYWA21lkD z(kp>3^SwBkMKSBHuCk)UeGZ*=>U8nhxAE%EZ=6Gnwd5EN`!I^^?aY{ij@iV=R$D1? z4CtEaqs=z-BK~n%{ZKL#4l}*vGEA9v;ERp-km`Ui-HV0(Q#xS7n;ZQWu$1uadoYd; zF-Be`x+qceJ+@f8L5)@|B0GL)`H*fMwN8BVh2_HrJ90A)bB2rDaYR1AbOg;>>NpfH z@aQa!H)|MfYsrJiN_A*yr^!VxNb4uI7sdk={v7}Alun!xUfbtLSEVp@wl1;&j?9)Q z>eZimaWJ!$8HC;iwvr=i(KV6POA=n$EAIv0BcFQ|M5;#lw(bsFSI@T6OFX%BHBtzn>8MJl2M;P)yw^l&JuL|eX`ewlL%!DDLy?69}%n0?Q+_NUF3+B-E- zZ@0rX8-3J?J3@>J$%94n=y!Opp)1UOI>#w4y)e34niD5wqryJ0V3Tl8{(4L78=1y$ zjhvYW)~MudkO`r3d+v_|znlfZj(Rs6V$G^oGA#~)tGM)Czx#Vm-13k@@;PaeY|#T# z^7&JEn6C`S;mR3rFh2@E5RcU?uFw&p13RCL^e&P_b_#pa5EaMj$Z=fBdunc!*rY8E zfx{7@w2N)h8lCR7BR{VooF2cxA{<@TU2(nz7r0hPrKaAnu7VD-hL)pJ=){zN^`qR} z*R#bcdBx{cru=Es;+lF(f8o0OiHF*}pcct_v&Om6Q7$L3UNIqr%Q=h7Tz=HD z*>SK|iBSDIw=*Uk5xMT3>K5T2?e`x9;+<-ld4i(uA1N~De}h0Zdl%Dx!}=vDj!AuB zLgzbH9-4WsoQmS9Fc8#vf}p1QqNteWYZl4Yn2?y(ux;M@u_u^tTRe=TF1Hkc+`-<7 ztA?z`eu@F?z793l&j_RFqp1ou1&Ea|-JI=|MW zH|n#d@VYtJ=ln~$bh0%y`5#MLy3TlP=zLONGC8%^ zxh=KOl;Ft*;EE7_;!#pJN^7OqDqEouJd>@JS9#FUwQEh?@MtswQUVn2 zilPf{m=YTGTotjHk<2I)Yr)4PkY_x$EBnj zA#rN^93?Fs#RKU!w066(gFpLm&OHu?XX*m!&owv0?NHPw6Qp>fy%A9sxsJa-m1V38 z?B_My&g^C$OQ5#-W=jON7sFZ?;H#?&m`-_4Ep-4d+8%;Yi8=B`=^u(O-oKsO_8jf) z4==iWVjt*iXxGS|_ZS1_C(>Bkl6VRAkQ#EgVbJA{UfG~(^LnnepB?;4IJBWGL3U%5 zHv6Ib>05TY4J}8Eef`xHRp1aiGBP&1oU&MX=S8^U0YKR~$H()S;Ul`HIC9!~##_m&D(5n3LHeTtkdkh`x@ zUARmHxkse{voteM>M62n%HT26O#1FEU^N8=(cESti+z8%HuIoP2Drc)qspw{S@fHh zc|11}5zFHp`JWV0d$^@_}00X zD`nTm-GmM~wA7>IqwXWQP@+JB1&iuTQDOd=IVy%SMim)`E?+|ESIpEblD2p&Fs1W&2M&95iAjdPBKo<^@? zS3mIPX(o$p3b=F>zx4YkicYv}QLa zh@Lso=n9~-R9XdUw^GBUVEEDzsV31hh6|D;ZFwwnYP*wqb36w0!(0jRqLUFkg7L#M z(Mu4q5ve9mad{82@bI^9ee-#P-i9LZD$QLLnGnZE^j}ExsxhgwA=8&P;~s~?or+?6 zlJ>Xy_VKeZ+?cEfzt$C0b_;9#ZC2~}CoU_BIZvuvWaq3AUvqhx^rPctk$VGsZdrH8 zlR8NN+dy1Mg@&ck!Vp^n6v3M|)#qT66Y@e(&(w*2%&Xv-2gUu?a};yvn2n2fo=nff z-==|e)!P+%9)(@AY(hl-y%E@RYTUNxp_mpKs{C6Thy{-vlbb*$gCM2x_6GG4u& zCNFSMB&Q`&v?DPLD*G3*c*~Lk)4p1h=xdpt!S3aQ!|mYyr#g+P9FKNp zpJ|tSpG6HK1np6#NvCxoUD7!1*A0G19?_Ni_%-feg&JP&;iUHspm{{p$ykrKt}a|HGza+wUD%qutM_a zy_k1jf&|}@HVT@=MOVHmuNziVeAL_zI6Z{)VqQ7t4;9i!-^J7ci|Ee08*}q*vZD=S zcNw}rt*&}Fm097U=6C2Cl+xzM2yaW5j?*)4==Xu3o+-86)r7b2>K+S7O4e0p4^o4a z*yL5wyOnR)HGG^grr zc8AbO;5;r%dX(6Iz^^ly7Ysqp%eqL=*keMl>*n;&!>wZe94`Hfr<&G7DV?1U*%V~? zwa8WOBlMz^h*c|-aTLC^%&z|9sLqtQu(&wZBFRZdvwp!Y@VQd4*;+}pB}-i?S65>i zS2!+#933tM0eFp()+HJT6r7Et|J77BHF0@ws-ez#Gs*M*OLpc|f@jsW4(p@+?6pZ1 zRmD9mMXEd-ZJwmenA&$pXl8%%P%M)^_Z1or;^F{^RCYCq#-2pI1S#$BQ-ZK8Wf~P8Kcuo6_kFdL!A1RvwU4e+9qhGZj*ATQ z`vyAKi6>Mw&R1b;-EGP#PZerl)XLV?SlZrJ49_{6#O9LMehDCHU+la+4YBuU>(d)|T(;H9S{!_`?tHlv<$#UXRFh&k=S=vB8=)q&RN zGUv!|oKap_m;6d%ErC7RN&ufeZhPv@CwHbOG(Ztjb7tO2*S+oBppq*~Re6Lm=Y+!# ztW&%30=1GN?p<-{#p>x_A@q~mq`o{uEkyJ3JMvMZ|V6mFD`aLGkP-;+;APFTKKv>bq4j+V8Z~1SsNVWjtiXzGeMlsOO;` z5oj`6*7#Qr8AHq)$Vk#|>Zlj-@4scm=bcH57$VQkh`uLtQ-xNYgmACUylj5R6B(~M zij`bBQLj>3nV0+&%9i%5OM7#oH7d!D*SqX$TN!8yw7$f|aXr?pq7xnRjtSaWz*io0 z2UrIO30szSd3lbVo!C6LDS6(#eXbw8gS=3i?&pJfm}}B5*zcH3RDto*2Y8iig<1C( z?qLB05FfS$>n^vs)w2{*x%5xp3e~4m?U~o}Kckm^d%q9i^s~5OTu)R}h+9w24`&m$ zi_HBZhiEz=l(BR3?zHYd<*;*J&dT*N$_h5hYU=N(Woa|}jB`HdfRU4s34xK#KQ(=+ z!F^+q(4Jb1knU7~RbpXN@8UA&l~v6fAGu!_EYSURLc?yFI}Sg4NLFj36QZ*_g-ny1 zV5Giau&d{Z+?-e2U>$jn)`xHUnc_pCr+A5HH}Z{N3Ora0#0)DhBrXpm_meY{#cu)s zPQJS%B&oE`@!reSCp0$HoN4!C@@g@ zvJF)RrIHHjb1M27JOtEpzHLKcY}4|5KyS*inMBjZcz@PP_T0DKscC24lbt|;Zo;2C z7j}s*?dVzpCKu!D&E`3+&XnKYZ*LgDZawt6!Jz5(Z2*R;J9kK1d(l&-W13r=DAk78 z*|&w}nAp%`NmVHOOh$PI#^~&Q_!teD7ZcS57*ALDlt*pRe~f8Vl6-cc@MqQmE%WPa z+3^V#U#vG#0R`)>s#FuCbv4x1d~$fWQ|>3(?DdN2%Ix8svQKLP9HQNf$^vFhT4&fW zv@6&VU~Ad)6tKn}(ddNBoDt4|0l}6p>E!yY?Y7lxfTCw>dR&St6YC~Hq&;^2UQeJh zogwCnK)yK$$nJc!s4 zCRlc^op34T*7dDjf2=C+46eC**rSa-v-6FSl~Tw#j92LV$%jy_IBy)4q?67Qn+n}S z|5(r(JnP6$N3pYaN%_svZ#9Z}dA;2jV|pU}9?1_biJ3l&LF{ZrQNi{&#W5j%c31IA zK!vM|az@*QdCz(5Y%_|pYpsh@m)o=Ffx-;Y`rm5kRm%7l*{b1v9va=G^K_MB50+6< zPrv*<_OU1?t3KqfuECy*SVh4Ep)zY-Jc4)h;Q8{U+MY5OH+qF)3t+n3^hCd0iw zt{vz5rk{(!eLrkxbmH#wNXbv($c3Vgrsx?q zjfey*sHW^=J57xgq-E)5K8A~lRM(b>{zs$X4Hbma-2_=C$Eel=bhX~1Vb5pJ?_RmGm&w=>BXiDSmZyr7ZdMFLf^oLgpla}49*rx7brV=G6R7tF zKiUIiap~bEBK07_8CG48Qim4BCqx!d)d#(++4huP4i=%%y_&ZtBdH* zusyfl*b zhk(}d^{-(pB!JJPDy3!e7HP~J<{Q5yx{G4BIQ)<(yjCr`>JfQ;jhrD@`Ly_fAWJYf zGt4QvT0VTB2@;z!Hc3KE(%?}I$pBoA-zRnI?-Gc!&c@$*AL+ox9BmL%D>U{jfbbrm z$%Sy2cB$+7qdVERC~Sdfrmso~{D^*!&|HvKT##PpDX`OXSP<6}0gJ#;dJ)pqP;mI$ z2T@1|63nY#RNEYs5MOb?Gb5pVSm3GT5Iq<$uawYh9YC1_(t#WE$_c&J!%C2U!l-E^ ziE4Wiq2dLjvl?8|1=1_6PQc-uAu?X$)h>9Bhxmz%OquwJm5haK>iT17n|_&dPMBkk zL0scN^CNvO#8a*{_VTW}U|5BrRim_=z#HK<@iL?VJ4}iF^CIzW52Ld1W1nBJ2X3GQ zW90b_QnM~S-o2Tt`aD3`XeBP%bDS}j!3LQ)j2NMe6&Poxq4KrQj-kP}N}|u*woA8u zLQmVGy>LHz&pW^Kr*oO-1gF#i4KPEHrC%k2SQ*3=F^N7ZTSgj18rBkzQ?y1MA}B`V zWY#fe4{B!ept}t`M%yrI;9o!+Ifodsf7AK)aYY@SMJ4vu(!|lD62xq><^E{QJ z5#&B{L|UtW18zLr318^QTX$|zauQymL?e|QE*NXmTFk56h1kLn&~#3{;c|whB{@4l z{s5_3n&I`M@MNBVjz`G`Qcv|!J5yt0whY(3x%JZJWyfHh6+eI>>D^k{;&_B{-*qJn zmRs2^NnMrhr8TzqP;6c@p7q4M2l;ZYhP#l4=E~Y=;TV`21#i$&bho4h%%?g@e#BVha*!y8sRoiO;;jX07t&8x`*4{N7`;rAD zk}T5Ly&rh<0rdj^lIl;x*dla5U4Z~-LL&5kpXycYtxfH|7}^-x8UNjMM|DH(ljz6a zxa{NK(^}%l24z_(+QJY>3a+Od zqm`{&X1#Ok&K||4!PT%SO97wFD&>WY{gVemGxe>>^Eu-~$o_5o+14NrK{@}$?xupH zH)QBGb&OJ-Z?{9uB0-feU&sxhQFdbJ^8t4C(5r|-matt{!hPswZ<7wz(+Mm~To zPox*r&r8pon5$BsAF;v>l)FUIcwS@bWDlE5|8W=jbw%FS8{t?C)RnS3BMCMgHC=&2oAaK%y58BHX-l%N3T*=yldBV2ftR4 z1-EDK)tmv$FGTM@_97y^Dr;Ifg&Xy2R>O`d%yGuQ-&TCLLM(2mR^t{I7VW9awODos zVQGp5QgM*20TB$&7JLoZ2l|lyUfzI$35SPoKd1UI`>N_?kCBdW_K*-O;nKkp?g|mW z0GBgMqVcy4n;duCJH@|R@@3$0r}x5XU9K73pQfGtRlp_1ZhF@*4Z5bsAm6?eLlf+L z@OtL^;1l{nmXrYLyc!l)?*Xx}rcZ;}F94 zhM@o^(Z$@|_M+KF)uQ7G=7M*iy_?Fx8SGID$pJjaj38&{R_3ce_Xvq)iUplgwm%+v ztweeaW0Y#;Ty@Dco8qR}&wr7MH#rf(Sc9Oe3xclT{}1T?Loxn$vRm;_vHlxci5*Vc z(zvm3K}&m;LPN7ki`L&NtjG^xxwi)L$R??ik|vtw}H zbf`ox3HO z_|Mw1cK;{pKjfQ`dWJ4eB~H~aeMw7!BIhVrpG^4gUdwMW)*(r?8&hAZtF_6Bzkukt zS=&&L3}y6c5tjsU9^Pa-zSp$+_V`{cPJ5xq@samm#CxiZIX$iDVr^^FS=(s}BnN5@ zR@L0I;xB~jH)@27YL3#Bj>?~VjXfUC-hitk4hM#TJCoKk4_ADBQT3|FT-a2~TO)IG;E{6@_Tbq3 z`3qztFL%B+7TgE8EK$x4OhBS4Mp1z>!knhppiPp4O;TKeqAEW!QcuHs&~u5k*yr)t0c-I;UQ0&(}_;L_DUO zWV@vty+G48w2ATGHq?hhEJ^^$mg>R|sowudbn>SF#dv?+DgyyI3M5cx{l5nC-@&`% zqznRY6Jm#@S5adwYksH(W7%>95m8~)w1K7ZDovTFD9AWS+G{PN{raMq<<)5rXR9a0 zLCpM<S@q^q*|$qu^1mT#L+x3xdrAWnBaE@pQdbjT zW)Vy@9@yRQRTkhQ=^pd!Qy|5hpUxc%nJ$R-j3BDJe?*_?-8#*&q;oq>MWm}v@mtaC zVYog{$KaMXVT?=i^6i9;Z8pWu2FWfj|byjL29WQ3kR$0NkoE%5^?vADG zwnTYZ6hxfYI;YFA)Eh_~Etm3PV;RJg>td8kXsH%Rt)6_de=)H;T4BN12rsu9i18gm zs^=xNW}4whG?W?~VnHhPyghP1F;LtdMftwkBMuQ<2>jIvpF(b0G1_CB91sMF0o^(v zj0IIq?zW1pS+Ww70Amw1g5TH%-k!03u1aoAvpc81xEe3Tj?=5F%VL>`{o9bcwMC6S zJi>fW3CmdCRU7?jgej3lV+a^H@hJM0hVkWd$?KJ0+(oh4VO+I>s(1|K*Aw4t-JWQU z3g$|v(edQQO?x(kK(1%~aBbcvko)KqgQ;$KJ|H069^-ad7vaeu+@DqK8o!9!)O}Y0 z&e_{J^sOubr7~dSrO0Q>RxuaN8%7^4^Iadt{i?A$?Jy#~nRFaA(+mwtjO#n?mu=nO zvL6|4yr&$vQ8}u5q9pBV9TDv^4LC3z#Sb{A=whfshYkpYUq?q^Q>Hhgf6+U-@IZJF zri77P=p=&tU-2^apA)+X^L>iiUxYG3@einHhL!VEzFv?%?*xn3NC@+KwQdy<>Pxs_ zEVYS@Ni_a6JNP<8`;AE2BVlVTlfQ>YP{6%7#M=zk9e!yImv9%_5gy6T2wb{FRNB2Z zK()G<`US3w&1dnRNH&c1!Z7o@rAnxDKiw|f?qR=%S%yc5M^4L^*MLWIf^9sL_kWtF z{Sh&E8N!1~3^1@;&>z)*guaNOi=ncm*Waq_UV+64e6qI+98K6aQs!Vw5aX-P%HRmyf04J0)8kJnBZNULFTzqjA+Dt}^Bkjukr#0OIux`yy!^#$XSR`7heStGmicAvU!KX%v4dkpvtBij$*R@@S{tmW2&Y4gEkMX9s#WNjq* z!mR$>{vYy^KS7y+vBwn$6qI2>lTPaY_%eT4tNe3VU?P(D1Rd#^=`0kSIl;Pzat> zvXD!x2gl4s!&z%dORjK4+=kO|%z6AJIWm)y?tCHQB+6_%|BJ`kuv4yNY*OVYw)mh_ zq#DFIn_7{61)jA)e_Z1|u_aXHPuQWB#z>KUJr&ibNv#-184cRz#nMvl>sd${$4^6W zKpENeA_0gwXsKk!@Vy3*WwWs-Wn1v1LuR8wc&_b$W;B=ezR73%p9cQ7pIWOFe(GA9 z9NQdn(QlLV)fHO|2dHH;*7zuwXqp5uqx6|nn{@qXcRnyhdoFJhT#jgB{;FL45~mNh zAFs3uyO+RXSY47Kch^MsWyOw57JtFF1l>~fYoHV>IUiG zl<7sI(@{)KewN4(OWs~3)Uo>;ctAZ*+Ow51hY7>Zg>N@b zoh!oju0e7`@c2hqqi3`(>}p2_T?%gcd950GeQ#g(Uf_Qk1xMc_$b$Zd=kE0-Chp>@ z_@K)uepS+HZr-dk>m{1^s!X1*QQDVA%oog^hv1=h+K`1e*DZ%65A75#J3n+}>wn^F z1?CebKL}qoAbipNpYio~+l0SiO!d?b4RrNl5U$QRnHw9HDeoiEM;@KzS#RMM90;Z{ zQEVvcSKJ!P>;870wJb-P%|hfEsVWtWFhX81WYu4hw)A@TumT6qy7!S&FS3S3 zHmSpUFGfTH27vS5F+$fA3jrMQ{Xw3c@Val-F_igO?Rm5K$LtN^5*#?!vGHu0>bAI2 z*^&KwddsLI&YRygKYNcJ_CU)Q>LPPc%8JL^PrUSw32vnk4mJ~|Mf==@7by>3Qb{#Sdb~=cMq8ai*fG0^moCIb zw2ji!ow;(*vA4v#C3gmw@zH9VHqN5kVL8J5;=Nb}Y#D33dZ6Q+msewFTg2Y6UEn4C zFna7bi9&%X@#rpaBf85kQEA4iiF{}EhRad5V?JW&a6!>1i_)I={K#5Vx8kx$I;zaK zt%Z;^^Z|IQk8VYP2vp7~nXM;`bp#T~M(YiNpOiiN^%N}#;npaMZ(N-o+JlS?UfA=@Ua}VbXN} z(VA!yap0Zk-CXL-B=p;-e1Tt4n9NZ~MNv{OxQcKu2L1fl6R&a1G?&&5i8wPeE+Rws zY+947+}Z5uYfDGwugt7%(#N$w(8k{H*Ql+`OS4MUd;=r8^{F3vDK99Q*C}gf)pbhV z701k4M9-lYEmR9vd@J{eY2N>7>EutM(~qqAFbtx-f!%0Tp^!Yl1^z;_55BO$1G_~I`Rg&^iz7rM=bN7=oY>_=EkUYKHE z@Sg=b`7vBeYRF$khnXwRo%WMc<4@POM?8L_p9g0AM}Ei?E?g2=wZ@IwXOg7 zB@@PK+rruw{8^-l*cf}YQgTmKq-RcV21{CrrY}ld#$>F$eD~;qjUZHOp^QrRCUZ$k zvR9O>Mgfb2)+$8Aelx+SLybDzAOj6in7Kyh0?T82;bCVgl-jeO$6JnX>WCwY6IHB@ z0(rGRef*_dNyYRq>Cf2x>?4`k{3Z88$yzbtmQrIk23HNiW_MX%$;roEO{~>Q8r#n@ z%rd`4@8)k!iz3;*<%PJ+P`BXRNZo0B5HD4tfUJ&Z12b%-Z5CScI8oIG?2I*Dk5g4$=rre7x-OnP| zShcy22AH)h=i@%*=^~Gu-fc`5y2XDHPFPfA<|4xxsSc|#$dNeimeneV%7I(YU*LBm zy5K=H!`0be0Q?4=8Y8sSAU@hz$g+hFG7_Lp1dD`)F-Z9I{UilIR0Z9`^@`y2!d|d_ zv^2qWf_RV|9M+1t1t*xZOP!60`w7=}Jnd;BNx#jdXLR&WBI7^cC=5NGDg%LI2s9h| z&xUUQ8#w;fm;YrVgbm#C?@j&=s|E=^&=o)jOA8W`$~3@*Q^$gp!4Sx%fMYhXoKD)H zUG$Gl_m}Q;BV6T2>Ni^pQi<>`KfP_5cjl}-J)IuG_>q4$n+CceP~+hrnNXEFEWw$5 z5U0(N?z{~0KTYiuv@j=i;0TKLsn^>8U28bfxhpi+V{AA?NTM&CF(o!Gz+>;*f66o^ zmRffw&B4Q{9>yP-Ry_PlhJ7%a68n<|QISa)M!#+*f**KS&6q@C#jpR!pns=H-;q6RxYfWr#hM64RW)MU6RHf-&&<=MylB7{CJf{}_9#usG9o zTQs;8?hptBcXxMpx8MYKCpZ-D4#C~sgS%^RcXtZ}aw^?D_v+baKfU%H54ZJ=|Ft0t zPyUot$Bws?EMBa$K$(1n9yC(~oW5ys(kKmdOa(7B{cnlNxVF3>XFe^fu}S!bx>M$L zmr`{ca@jS;7syC`%5Nx;w#;bTsG}IrRxJ;=k3a_!>!{N|((vBl-I_3&KJf0y>yalo zFG%j}hF3ISG3z|2RhA)rT@((F#jll%Z&31OUdy(_bvIKH%cV)~02)Jlj?T1|#A#a$ zVlU4_O>JTvVRSl{5j6EJOq?O#>nUUOveYSNnqd4g$p2w8m`wfXygwgc#%N_&rF1d` zXx&BO)zX0Z7*?S5YI=dT8@s(b(nbNC5ZSbEJx9o-p>aWh8mOn@QfLwDX=L>Ey|$4< z!N}=4#ub8V)*$^}ya%G3Bvq2gM+X-JjDPLb1s?+Pu`^~#W?2XIo}*TeGz{lw5rki1 zC)!H8q&Df~`dsm*NyN@6ZMf!HPI$;W{k@BX@NHFAaT#2#X92?TM!L{G zIK$tvj>Qi^R`TT@VO;^l0Do7X{(kpfPaa{v6UkgayJeC8ttcpi6o?XbuBMK*f0YFg z7XJRfKao(V{->J8ah>zSY8$5w9z{dLK%uL7yJDwQ!Yn7L!*W3;IXa`zr0#%x+F{_*4L6u%Dq6#d*z34nCe7|4$;> zw#wxyWC3-5Q#~*BlzGL|1WJp@u4; zG@o?rhq@xrI)qWZZ;ryEYb3 z9XC0-CBi369O8=G7%aF9L`E&I*#Qg&5!=sQD#ttL2@VO-Zqbt$9w)~OP$H5FDkht` z4^_E_lX_`=f^mKp9~kAjBau^ybIu?}DX0B9QRfASC`re36%o4pUu6T|Z{+*XW`6T~ zEJc2X{Njf^!tCaacA7oem2)LB*m~sfX71 zP1x<5a7w*!{bzVO_uwkC;DafQXUJ@%Aa$m=n*%H#xm6d-=92Xyb?>ld|7_-y9;$n; z7*E28(jk#&i0w0Gei9ye^UM`v*4e#7b2D58^LvJxuwu$zQ2#w*z0;{vZ2=W8Wl(4L z?=-G|0QUdi+x;1&^1HVKu^MdQsi9WkD+1hUf(;VDfA@B8SBnhv#apj)I~HWHC8Y;6h+a}KVvOucx)auY4LU{BPkA78AB4?>XI$f*i)ESt5E?};}m z{!R&Z=!cGo*^o23M(;Ru^7VBrwo0qN-EpMM6J3y>;#ITRv|Xm*I-nAdOpSvh7z4>c z6&7vg#H~;wUJn6fU4yQe_C}qeyO#a}n}^6~1+{8Jxr+TN)^J-HSMgAvs!;Fz>Ht62 zs%%HRW|(nvA~VH?nekjJ84rF}2_vS~#GrNV7X=_p;D=^iu?sWa)#w~8dE@vH4K z#wTF0p|yinZEyx9rJ5ZZi|^v0em8`4W5kd42#KZQVTaX?X6NF8I;8{{9FWyLZ6qqB&i@pnEtZ8c7Qesw%it$?h=YkM^X>pnkJ5q{cR>2$g*UOfM z^FqXq#0L4eQPL5~hr+G^?>sr=A`3*X6t`oTm|#HYOXrZR9fnpWj4$w->0Q<_c-D0z zT#PxE6aNfLwmIV~RN$ulD`dW4to<`!+W@;4h0r~eR5?r5ILjocA(IokMz|PGT0l6x z_=uv|;v3Nqv~tb9r+-8YUEkOCbc5i)3WCGG3&#F0aQLg6`^!b^H@(LQRf&I~I)Dzm z9MsG)u0ZxzSHcDz%V+hK~cy@hXa0tf3WdgXl}e|*$Z*q;%VY~2yPndRKeoD8$X!LwFfbN zW|FG3%#MclY4jxX#)PS(YzuIUrVg}F^Twkz)!0xaF)K#+2Bx)kKY?W2GT7i|G%lLN zVk6ZBaY76tj{2$63D(3ZU8H&+snPH*}GJT>WZ}^DI5O z{V5p6_Eo@faKc~a+rvOZfi=kt{h~?b1pkY4R@p@fiI*WG+F zJcL9=%Y7wclN7HC43o1Rtj&VhtNltZ1h7>mF(B9iSQr7O^F>vl`gdHznm+b{;Q0wD zA#-F?&jFrkWB*MWq?t-;pE1JieVIpZEZu?!`=b&>bP zeiemtQ^CB_5%$~n2ih%mf=0Qg_FDvjJW9u@RmZ5D44G=FwxhhEMl9!FnKLvK4X}p( zMnk_&QLvJ61}BjV`M(1O2~NoOBS znOifYKpj?cyh-}CBBpf!(M3C=nWYfMJ;xJEMGW26i%s`q-goOj^Y`eeGs2?tEI*+5 zHtp|up#9W)_o#Za*n=FTwIudp?c9x1`!US$B!Lol%Zac!hnoG& zz<(NJ6!pNgC z7IO`(&>T#QkUR5Vwi3RmpG8c?bB&}O3v4SeLa+cBU;pUm&N2yx7*Y!6kY`UCruenb zs~+B7FZTuBu`7)kLDz$FOAcbqG`V+%*5F#KxxMa5wsC=XBKpsuj1B8t%?t_XTdX>E z`W`dNlA2@ZOIL!*Vc-WY!$qg@h^lFME!YkcWROEvV3t8@HO#10bBiq#ZF}*Ms@&1o zfw<^TV3Zgw6YYC=r5*o8gcc>@KJUjf!6H1^}3IO{N}@x0VQ zo!WNXn>^zUbNp%apgVh5)k%N#u<+u#;EahDp+-i+*%1pX3wc zPiAdY2!qW{8+v^IX%CH3*Xj&K^3S-0ibQBz0-3+wLt{Aq$~noP%zTJ05KTH7)mD5v z*zwbHAGE(@+pG@e1Mbk^KaLs9f63lnpa~x91?#)N&7GfrF|ee@eFl3+m0p@3xUKTs zCVE33HN{HzIj@MfQj-+w{=3BhJe7I^M!Dpi5q*{bMUqH-+*h3!gflno@hyb(x$6V) z&VuC&2zzAxI1?ob^7)qQ4>dj+jGv?#I|ZisL&HkMC{XBR(JFN%Mc17qSy@OuZx`Y6 zXt2>LDbPCDq!Qa>&5d#LXTv5|vfVQVd3<-F!&X@rKJ6GA+_XKwdeHmx28YxRkP{Bv zFlEJ#$3EcW>6A<_s*TT18h;7#XjvL~B=r@_BI+6{B zvEHJx=v-@BAqkv%24TfMb3&Tux9)Szi# zt*v4V`SmzAF37XSFg$TvF)(k#qoj0AQ_Zj1hH1184l=DQ|JX}-^$VMQU;>VuC$rj$ zVCbDE^Ij`Uo3=Peg+0KVez(61!Fm)cKW0s=YMs=nB)$F^&ryOG_pK}zpQ=UKx(SbL z`_eJqP!dx$%}eZ}J=3EFhlwr4`SX;LAh!`Uz(%j>1u})&y-Z2j<*@NLUsW{}jpL-G zX7{-B2f3^27()bGGrGdfQNsXIyrH{_c|9?=g*nI=fA;X4_5LC0H(`~7BdD}AJlZ(U z@C-H?>G|6zGYQk0!WLLEE$>;wHR|_WPI-+cHNBv1SDyC4G4UTTfDZ}}tdOo#o_(eR z=;a;2mw3E_exh)Lt(omPJm)>!+_%0gXpVH7JMBoBIPN2M!!wA)1a=2M zr~pg;0xND$VNehUXLeU$NW4``H0$LqTaQ6p*YFTjr!&a1$M^&Pe+HW0*K!=ItP~y4 zrJN4**2({UD`8>n{2xQcU?sWVF1MKtjg708R^Kh}^8%*T8MoBvLUSm~14cLMR}EA+ zM$%0X-e{3Ox?jOO<@Yb!#Q40wF(db|BWJn&asLMPZm4Ek2rL|v^1C6@C}g@ZyCJLD ziT_5BF(DWDK1ps6J_@C)mk{Pbt~OXT5?cxS((HjhISgDQ9-FnS9GcSOS9_T$(X$qz z);;EUIDdj)ZZ~R^T%^;ja!Kg%prj4P0}5%2p|8`UI~gA=q|Q}F0iYv7BLSSJMWe8u z6w?UYnd>ixS%g@hvJgqTC*kW;Rp8nh3#~-X{%Pm{7|X|q&naXaXb+drMe92f?4J>J zOGc3C8h&byDGJOwRkavKBP;E!AJ2=vS23sr>BoGUV3r0guMSIcs5vR?-tA9ZkbUnf+VMoGG3)7OY^qKZQBtp^Dz{h&c-JRpw(J{1TS@Hbs zr1$&hIUq1={B2)F0y^pa`?3_&OMs3Dp!ClFtd0Kq9;uxwtAPB7mFemB4GO^>uLA;B z^6bBDQg4(EEaXS`ZXx>yvkPvqmL3+2{|>T^p5)}-MgGto;<(lTRlpbSNzy_NCESSg|n$!hLO#m799+9aQnmD9d zX^UM_AkwV*va!1yq&mxQkhBLKDSDgJqY_SK zEleg`v1UsOCIRb=!oC!9?L>hmweC6S`|6Xr$6$|E`FkQ$LylxIkb`%sAZ;4w2Z~siUd&7t?V#kGSzf-;{C&<&kUq;v+@{&uwO1Za24i*lc?^L@L`SteI~Z?V!{Z90AtQ(HMpb;qNl?PCC$JS)IL zA*B@*p=R+&XWFcl($91HDxpTTAWAcow-P?geEy@YEstXzDp#~Ss$|c4z~vSl7swp< zAxn4uK8F^5mYjVS)pfFM+Qqx15l*h#YAQ%;F^SRN3&6lL&Qh7dF-0$Xq1yzswz3ZH z;A!yvY{fNISNe%pa)U&U&SmS32IeTRpY)*^(h89@EUU7DwGZ? z8F5~_saWF68Gp@lL(6xY7Gb#uFt#+D7T2v(l_%ZjVMLkEFt{|{6km}PSy0B@&PDrR(3Du#$imOjqQ2RY;PJ&CVc9l^ z5;lGr{M^Yp2!~f}E<4BhhG?Dzc;gg!YxX5RT<=N!G|tvOAnpDCW?W{CS=;N z*+MCYHsH*J;{S&tfWJFSXA5)`!F|1C0ha^U_Y){#@caCBYTf3U*GL<@S}} z#(ZYPpDWUu%gAWr>Y1`@7z32zQRLLB;`+6L6}wpE_VL7On4bBSa&X+x+@^-3f>=Ts zT@W~1k--)a0MxCs0mfl2ghQq|bsdWk;>O1Jdb45(DY2h%tghN9skIKC8;h+P5ZF?< zO>m}oqU+V|A1`h7V6rMES!BOiN}aRy7h!vn>C?(cm8R$Hv2Q1<^&xFGx)W*3wdeMx zf36Oej@Q?{fnL}CRzlriqNfm!T`4XFi4R(>I#y9T`6j?*ak)i0=-o;-Z@nFsD}Ei3 z_bGR5R{(M?YDC4Ctttd#fO)76lNGAH+~UaZz4$nr=`{w_*?*&)gCITxWR9NIDs#_+ z+3{ny6;T_)KjIR;&pF5s*D}#4dJOM>|6tYkH7{P%B-k4K78m3l6-IXZ2^rVyf#r6u zsVqW1;GDwQJq^+gXX9|4(1@q>v#$CV)X5gZAdHW*$rcA@oLK0M<$x3?Z3bfAF( z2~R)WaW0eo1Lje!Wik}S~_aO8hwNPDl7@6smuMxOA>v#_z1_#HV1EokAT zh^!3CHa~!CfjhqXy$74G>*$6>Yru^>pn+U&VAh8D+y%O0$N@AgRp%q{H{7Ficw76~qTfk$*h*hj+56PV6Yv{pEJ3Zc)9 z6A8B6QI|MEWdhhaKhO-C%g%Dj?Vi!ozsqh*RPm*Zc~BzkJ|Esix)8Uv)WUnDgpbW# zXAalw`FrT}Z}bc_9=jBQ3f3m5VEubw=l`I`)XmV*8RjyV7!@hvzwupK#&51 zWbDya3#=11PGh01B_-wPQ`?Ze;}^jhDhki5lI49wH(wZ5#v7c;ku&)pC0slk9!R4d zgn9FmCdD>?OmfBly!5SpgRY4dhlYzRV6-#@NC8Vpe0ptS#zbB$ZY4R>i9M#0sye3_ zl_}Y0C0Qcj^tsLf%&C$+b@pJ`xMn+H zbVzELYjYAne5?&8aE3-&P+?eB z6lm9&Rw4?#AILS6R~|}(r>?mA_K^gzFv$q2eC=H_)N>D%LjW4^YR~uBEmaU2gvq#$ zUKriyp+NjL)nP=cr059YRYx`nm$R$lP?(Q5=h5)1Rj-_?@efhb8@b_A_jp`OM~<~Z z{FvWAW{;%P3?!7yVf649;{cY^9a|Q+{H^w~995h3;M=rcwxUs^f~Kgh-RuogFHM_C z6o7jvl^$htszVPV#A4lzjG-2lZ3Bj>^Z+`oqN==Z)YU3OKE7^?3G19mTaYsuy06Aj zlVz~Q8KX54C-zQ8{iH2Jhs$1Mp4a$z*`;}9{f-IRrm13|Exdy4W;XNQroHoi7&jJQ z*?NAB+<;;a0#N_uQg^CW<^nZ^P9f+=y7Ew*K7Yn-JNt!-2C(JV)7#j3V2S-ydAqiv zSS5iJVu|~2fc6shMIq;<_wx7kzUUo~x@OkOE>a3TnkIJMvHNW!#FLx9#Sdx_Q=uPZ zWwVVZ7&@dH#sO&h05qUjHh})zBR=zMKpf|T`Y}VztR=fk__Z&iM|jLzKVZbk`$jDu z`+1KnzWQfW|*m}1Ht3)tektqr-v88Z_ilBp=c~I zXv+Y$3^Vat&12;8pAUH4xHQE^IOV6)fy+l)92RB=#Q5OOE+|K{t%6n}{>jk(W>ZjY zEEtpmu!%g_CBiOe;Cwmts4xtfJLFLxqgGkZG+GdT^84}5gz)lUq`m3ttC;YGJ2QSl zdZ%@$_&yhyPO$1OS)coqI!MAxLM2juShDN2_x87Bm*0@Tc>2Wz2`ZRLAlTFX>j?2j z2Gd{Gj(_1je$#G_5oM^$w!KKE?>R8J2R;xJ#|8#rr_oPU$v+l60q3MWLA!@6D!)Ii zUmr@+T9TJ2>qkCHN<*0@SWm>1+k^Lo*Js~f*ZVYn5-oOletG`!!H9{tCoDd_=YAob z-g}cl#kix$rj+-_K%;7b(wtsJxF=raT6x*j61*B(-EJ%q9tHVEz*$_zQL5K7R1D<| zcK`Av*Xfnvug6&bXD(dhq&9y>C6T#au?C#7IbPOnA!K5T7)w9)^ zz+rg|;-~RwlBtEuk8w*#G2To!yh%XPuqc`%Mw~C)QDX5pEv{8}wb7 zF=|JKW%2HyR@zvBH%SX2N*{{QthrVKop#!dCMS&#0?b{D}O$(sK%fF|v$bz~qC+9!RCCv?;%t`+i#Ga)3M_Q#%6UK9|P;Fl5 z6FB@VxMRSjpj-hQI2RMDvcQwYs_jbQ;;Lsm8AxoXp}C0XEUz)nun7WO ze_SZBg&_`BVCB#7bxoTk?Knh%hF9?s_94Vvn-KimiK24pM(V}y%iwMq0mMo_8~b8i zi^ozi86E2fwtUBdF_a)nSK??+Irbz>}{!;Y15fd*dh@Yki z=q4IA&EX3K1V8%~GfCo|n#dQw(oh=2+_J z;g!eoXtKPrnAarpK4z*YyXbUTIqI|GyXqa6HMlk24AY-na}%huR*#Y@N8j~-s{e%X z21b#-wWk`^4s|iM)zyK^rY7}`X3`fc_@`Xs?%H+qvuL`jt{OvG`m3;eFGVLg22L_g-62w3)n3sbYnV^)Dr%+#ArmzV=j5_v zbFF$@O|0veZ+n{TY(Yt+>J9=x7@^7!%;Q-L@}3f9Nxl&&kvB288`*SU@R#5% zGrUYSj*{z>kmkYUieMb0 zM148>DE%wJyc2x}9T3zq6U@*exH}6+?td{|!4jG8jgvndgr!9r0&dr#qi_B6lQBW*?2kwqX_w1Qyq?|s!jVDaa7HuFDJ!WCPp2m>)6 z(d%jhokUDUB?R(W$N^dqXA1k1T(fbzb32GjDCds;K?FS?hyYpxFlX6<&TMFRMpJ1{ z2VXY7f>={;yHEIjE)|8Ky(9z^x&tYWBXf!N#C}m>!H~C)Ih5Sctb|-{MMqIRh3eQ` z`@YDwIj}$dwEY>k&wyP6PZ&)ETA3VZm^EVTM3=a6RiIMspk^G}+`5Pcka=hoN>heW zmYm7OmIX=ZiM24>=E<~24&DN(qhz25<#Y!jLFlt{ipWv3(ub+iH)ZT)b=zbf|9qZs zZp#7B)sC$ssS;8wE4vHdXA-z5ru2-oSgog*pESF+SQbJn{6K7+x?%NW#U?bqe65Zm z>!ovEx4mD~tBC|Z*>iEn-<+)ysLHnJSy-UZk~)PypQx#%E*Z5_#o($PRR@d2Im1|B zb8KJT57BHaF_~J`+TU*f#y=~?q6F0OX;+B0SWSqktI%NxVgLu%fQ_HO(eNFr_a2i! zA5-57m1|B|aG%PJAb8hzg~Zh?R!nJX;NSB+bUoM2Q7|tJ^R1Q6Sx#LQEdrpzH?w?& zR8hZX4*sa3*<0tIG#UDV(L_Gp?X{^Qq6By`&(WH1YTtkLcK0p6`y!5^RsT9@bV+$Z zXQDTI;tBuC5B?PW?chuYPYI*-@Ep|CluyuQldIgdC=V3f@@1#zv@Z`XToX=rK6A%shkv0+hbpV zYzS}@7R73vHX7cw4K+3_dc2CQU=`aNc?>Pn89>Ki{Cg$%-B-we)kU}lttPiYeZ{}u z(q#WD2Jo-WB0&$-SzrM5ADwLa+DwhVL{``OxA}$k6P%<53Fb(nN;{uji9i~_+ld*q^aCtmc!2;fnjsbfkPH{zw1CUdJ`h#lfIlr?u~LtkTr~QSo5+wQ9J~HO=X)u z;muPl#cY*Rtx+^-<1W-M9_BW~TW@i!!Mx&VQ);+dVJe%JIPJoRbj=u;=loydlpy-J zFn68oUtB(PcjJF z?VOnu4}hklWzIWh8T<3Vg7HQ>SU`EJcF`Ba(?or;fnv;j&HK&(@2q6&>1K9JofdKZ z&+2}sEkf63o$XR_+gP^fHLzvaLX%`UY1uqb2Ka7HTQD!iO4eSR(>H{f0Uj|5O234a zJ&@K@^DZZ(of;;}e)xE;_=HhU0yGE6OwA0+4YuA?*WdmT8{FqHjo<@%JhGr~=D+W? z)W6&rXw*mu##$}nECevj3`8PMf&Wu|l-`|j7l;H@+8GfT7gt~-V-^Mo75RcAn zDQ<9t0sM%Xcz^{mDGRrT!cr8ja>QtH&DgcOv^Z811(-P!tD&UFZfTKBJ?TO>-3&j@SVgG*xZSGTy1;;| zg89W4pNI`jkbN>F;8_L3haLi&Y9#4Yw)YT)Mm5M~NIWXOsqbf4tTsonrK?1DQbuotvPwOyg_EH0x-XSK;1_f~gi2fQ17;5Se*l(0CVBD5 zxF&^{VmO(@{?{*)M_XAdgX&DFAEtEyy)8KaGdM&Wc?)cFgnKP4NPYh65L&WI zixE*2CJ=b{a$xUf4jqs3#o$?F3?KjyGw8&6(>ZQms~62^7YTV+kv51YG8wUEob3fx z+Ej>5d7uW8$VeFn63ZR4H&*QGK(njnav-WE#{P6?R@4H1pTQv? zYS2HOR?QwIlp1ZcR(LOFtMN4Sty~mKdv-@YzN-yv%#5A z_fI(C;R1XqvO40OWLe8)^@UXHJks<{<}FN~4R9FqYI9XNwvww+ah2vgFyfnZ+U0xR zqPmL&3tj%-@q_274tzhlh5yt@9M&heT^#9RKd_7U^&V&NC07KnX=}t4xWw)4DHZ6a z9Q$9)RE43PByyp9g+kjxcs557#P=J_mZm0~#hXgozamIyzvU%xr_SK)o^``IeNOC< zNj7vNH}?j)!=gCbk()cAndrieXw>MvOc$fcretEcj_psHD zL#Y}O@S zk%0MLekhzMGtjO-M`*DY)`b->sbBMhLK3)J^VDYxOAij$Umw~V-|8yY1mkgLqS%-6VW{B<8~7id?C_0WGf~^jjl|*)So)`aQBQ~3l>A%>Yy_7vv-TpOph4sTvbjr2 z;4i=(9e=c28pbk-T}Fj^t%?2~iVzw{iFOyu=IAkW&xc6hB)@ctaYO+`Tq+<5n*eW2 z^J5EKtiEbGk=#PvxtExsQry>VC@hEMadzJEr)-0?)U|kl@ECfp5@1W9=UxEJtkvk_ zCwQ45nf7{ION;iN#FNV!&k&iN{OX9fYRsV-y^amL0^R$*Hfk0~(QJo)r10w7a)Co~ zHa8OkRy5)kzK^PjWtXkrfRntP6D`6yPPz9ZAnsn3Ch2%M4k!9!p`qds)B9{`kLmCZ z!#k!2r!EtWSxil~ecNPd9m>L02?yoA*k~1ZS%dv`3|v)mcXUnE><`|c7%v=ont~y? zJmr+8FLSkL4rXIXV48=MI942ayOE0fB9YeAD(y25H-W8$)BfWUeX2{*Em2J~II z8G1VS0X%2<6=)jGJu8r{0aPpM2bZJxF`>=HW$l3#vt+y)ZC5gxTV0fRycbVMb2%!^ zpXT(9iN>Sf$$CZ1nuOwV7O4;85h}P;L92;ZeYmjDOWITs5oU`QEk>e`~yfOk@~jdOJWsgl(2eZsPsP1_e~6mrII4lr+c%LqBl7v5xAY> zDBSFO7`iHiH5eDOt))u^0fqrFQd0tZ?w!DL@aq>j(y<=mv+~G2m_mUAlW&w8=r~jk zXcrD@gM4|$6XUWP^Yg6gmp!Cv40CfV)5rq;e0d$6cpv(&i1}x)YM*iV4S}E0ESIsr z!r>k?K6$@4sD1w!-`%)ei9?MQ$ZxWgR&lqY9L=IM>^8+Py$(=I8!O3feJp%0e22Sy z7P~K_E-7GryX39acS~Ac68vNKDp+vQH|vDcHD z*NUr&nlrEL$6huVs zOjLXJ=OFs|RpY@oq<+HJZX-4HL<7^M<_TAyU{0z@YOj$_+{Do2;zl=X3c%fJ&dAkc zBgbPWHuL>g#;WqwOJU#%5a}RW1KASHJHqY@Rv|q5NZB{~v1V7n(??gO&c2eZ-J|z~ zbssumpFCMpBpECbXhuej?~@anu$0mr4XOjK8UmN1>z8_pHp33x=gS*trycQQ9*DF- zyY{diksU2v@POvSD_#}FKpJ;224=1ZsjhytuoS9ADjMxh;jyv33c&$^rHD|VI3gw< zs~l!yw5P_EB~x0g3EV|kKZE%jI-TVUZac*cPZ-3ak{g1=ur^Z|I>)>ZLLWzo9`4u1 z==Ns;+kyo3JIL!(u?EJIG5;!avV>-OJ*pHbW$99BFzSZzca_`*RbPXZG4sA*N$Vfd z&#UP{o4+EH2~Hq@Ut4BFm!(3l+!(_tjs*y&)k&;=@@!~C0FO$JGS{#WwE_K=5>?X5 zns<)?ey;#QAl#4|-A|geK?ik)x9J44fD*degf6q zGy7EUi*#9%c2wdQ==-r(uBvmp9sOM;U5Zz-&cSB$=YI&PtN|Hcf1g@V|5vWze^;PC zTiqnJYn9)6Uv@ZMSPg$l?FKQZdD4>4rHxIfbVXt_?@-Mvb`>&=@uPKZtKGcDud?r^ z%s-boI~UDmzesR(PUxZbmU5=GuXlJ~dTsh#c1-x%eR_p3And{!W|SSxvH9WDi7B1p z^<}lrl&C^{-jU#?c8Ne32?82g4riDp@wpOWvuVDHLAV@s*tNSIp^1(}feG-eR8HcG z8-8!o*+*Arr*lee|IM}W9WWrwFxA9u==!}&is3is`I5Sm=}>j0P090CRvh*hec3*S3xTR(R*y%gOhAeKTATOf0{^L|0pKxV_g^xW!$W& zhX5Ui%)SD$N;fMtxtT-K-O9Etsk-lL3+&6t1ee~7vvBc#IMh@^I88{6MYZi% z73Le(wV-I{_oVG)V?Ovo2_LQ)H>g0|4@9;|z)}o0WR6(Z$`Lt7f>NF=&9F8)RBL&rJ(vS!qn&A`uuLJi0C4p8^+pGZqmN1aM2G{xdCUPsc314itTo+X`OhP*1QiO{SVMnt~q2Tl${pW)hx{BTl-k5zgYcipf3# zn)G3Y?_Y@@+4WE-=L^q7eWVdPrW^v%;*8#Y_7TJh&bORa@kqxe9>hzuE$9-0wAV~% zU;t}IU2ZH3h{W9y7*<7zDd~L)z_lPVzk>}JIjn^4O2ng2J zsLP{QKAUynWHY}XcxPJs3?`3^cM{00(w99Op9tI<#H=NJx!f!Y0=hdO`^d)uQFBRr zU(`LKcIuaRN>eyHLKr@6eKBp~6pQd>dIet=c+8D(hRhMVr091=RMET)<{}UwGrT*4 zp;aU*vJ+aF1FPJ?!y)QDd|9R^G~kKtUQ=+j;yZ8-DST)8;-Ab9f49r8m?Un)q3#hT zd$p5CXx7bC`dR9WJ79c#v&6mzWgv9-ZHEz8de=i{=^po;9b zzo}1tk3`^KR@jq3BM}{F3CQ=aJ*Tp%v8nCfcH8VBf^+2NEG^w*HVz9-hZ6 z7EqVOBj8K$`mQE?h^v4xR%oS%2#7QI_yf!hqUz)#ktAXp z;D{u?#mGD3upWg)vS{9W<;@ZOWsy+4w}qz{d$bB_#g4tj0)st>^0r$6+}35B5%r33 zwwBFKOgGNuw-*_7Q&v8~Bo_{7Fjm#mthRfuuWb zQCIsq7ELn6C2BmCB56s!w=C3+Yld-;@BG#vW~lCdQ%`mkNV-wH;kyv=ka>L2UWoK; z^7Rp%K;31|n<_E16_YK%r1E08&=LCui&$eu>MR0rS=up=A~+b!PqQhwHe+Q8aDXHI zSzR#2Le9#{dOUxzm)&{7M9D<+V*Ma!)~L&?c2wF}Bz0<={=(G0%jEz85Ns@@OmI|m zbaJ8_hD3}^h?7|YJE{}a=*R40ZO7XK}ag~pza1Nt@twfTh z|PAJ>+8M*12R+abA` zn0x$A?uakv8m(0qbj#WL=~lzQDrJ~HnES9pNk4bw49*xxV`FBiAAaJeqIacX!hi2K z^x{|T+EH(lXVtPnrhS68f6!%k2Ycv0#b-VF!Mc^-+9G~Kc&)#(iEfL1nbt$*Zar7^ zSSa_N)`QRh2l*OyEcNe8oZs(V%RubcBj~-KgXXM%zXkpCz5neNl&Pkt^4mP-w_12O zgfbw!B!`ZgW(!7BFju>$l#v99|0$6^j((loC4sq5;QI4XWIoa#&wO{?=7)J{C@(2T z#+s9(lY-;p;$=tnyMs8n9H>exBleZ)$?5tDx0YR}*8Ph8=3pzFl|$a+G$`PLiDf>7 zgR`dO(oxXFR*AtFl|m9hC2U`FX3iP6Su<_Jt@xkb_XFUI!83>#8jvCqKEA+Q22gry z8ys(I64H;U&&&|*%I#r0*kM9>T+?mUl8WpbXefo*` zlq|p6|N1(D-7GFNbhF5ZF8#S$5{+yZq%F4ijL8>J1Xk;HgZwDC{dALq-|~} zO6k@|i#%_1me@W9_Q;EV;jD=5kNFss$c_b2Z&k^$UQ zy=2aq@T@qz1uzf(G1GwEzTu{I4@MrRC7KHms4YDUlbcrYGs@E)oPvJ$%CSN5P*BCPK6B#&&5VYVud&ECH<1)YWChCYf z1@HJO?%R*_`bCYk^iKPBpRN%fb=KPmD_pQ>P8i#E8mCewMmOtN(qhP*hX%i=;x#eG zApr!keZu_1fZ|#<*lfk#!WmyH@=S1$@f)Vp?sw7Uxs57@Pm-ko4nn4xPa`0~eOJt% zf_uH|KMW|y$g1NgM=%>DimLadYEi$tina8G0f{w~=^w{Hg8N_BMzgBCJDJ>F(HIu2 z{M+djZk)zdd*v%tW!wzG7{nY#F+{leKBqj2N2#u^Iv~NlddFZb^h&@a>pK7+zHo-i zjHI+qs*(NM^)ua?X{vyLxmqaZMSI*-6nv?6auV}O5U(b7QQm_y^dk;%MKRb6jIP#5 zAFp0(eA_=bBUR{SWqM|3s~6oL%E_;b55 zvL)9pxk~_K2ZuNb8&O^U-J-|?wf7>cT)Vk2U-Tf;isLYIUFitOf5JSz+XZiKV!(DS zXU3Kb<*|~Sr4jdr8}YaQ1ipI(#FOi{3_G+aJe9eM`+>)9QKv z-3Hb`!_&VflKu$>MMn!eM+;{Q&p-Ipzx5t}p+Z^4ZcY&8jh*3eduKszjD#)*oJ>A9 znL0LB*;D8w7akck@nujiEh^H6%ZhZ1!$EL|n3HJoCuRTHpd=|3Ol;wD+V%LOH%q&K zj}Iv94(uU=GS@oSC_fyp?fPth4uXjZE#c*I(VcCWL)t`!uP6W{XL%+|-lBcQOAZjp&#RR7^ z*CcRr1FVjB1Q0uI^7G@?jRH0k?mJNFwhSFXF`oXB1G1-1{Lz%VNb!CWBw11f*dyVd z#9rMG4C zl>w#WLj=9Aq+L+1+{UaXV8Sr|vp;9D_SwT`(dOb+i+HnA-jH@)4E?G*fm3qN(f3b9 zPw--PR0}SjE?G3~rW!kQlzQDbvuhqu@e^BFQ7wRizL72D_P5(Q&VU|3fi?=`S?2P$ z#-(pQX16vfE{A^`!he5QM;wbfNI>t17sPiY|6f}2ztJ534^0@YSDI0mbq5NCk*IA0 z6BQ#s7rWN47vu?S7(|wl>Eaf!pZ$bwnN*mJ?Bn;rbU7hNrw)zqU}e2{%K7mwyQ|9w z6x(5mhT71N$~GO2BXUT%d05o9PT)k>MFAg9{4nln!!|J;Pq1z&0&e3#irCO+aFp^E zeY}1LpYP!^K~JMMDr|FUXwk#s9|9Y<_KU}#6V>FP$#rXAvs!HtWC#NaWj z0S1vV7tr8Of1bad;Ge#4qJi?+i!%t@$Awn;fh3(w;d4Ry zfcbl4Xj`M7qDEzRI6E(ER1uACch41S+07%dFojh6&4{TjefGKi5g#em!8Pox8)e!B z9W(@N$yUv|7Tv$QqwmBK*MD+N(nHg6H8><-+HF&IFiqfz*Mibw4tzAdh^YIVY*J&D zG3M_)LVt3D7EF_#u-Z^SyNX#oTKMgXgRAGrG9K!}+F^6yaK%*hd?koyiM4kxr&`>4 zWF0v-x#_*u=vZDWk?yt=S%Z}DNZ=9$hsiQSsE1CwO?AM=!c?*BgmfwRzLT9=iC!xK z=~aMXURgrr8<2{9!&mXr)3>7k{<@^Dc*&d^xJ>Gp8nIg_zrou#t(0TqrjI2?xAFbU z)k0d>+44iNmu2Qy{Y?j;N zC*n1O%b41Gp&NDGH?{tn-Bvfnpiev;k%Q?S15|oPP;6@SV#d#62riIic6g<*{n<;GL&)m@;6(@D2>6T{K_#ovfNN&XI|QB?-=NdaOl$J? z4^z+a11Kd=Q2#OsItEhzKfp}Y!~Q>vd=(poIYk^kxATR{PiyZP-~&E>w9ZjQLBYiX z`1hNH=W^CR9W$R$Cc7SUM{fR0^vO+UTwQ9geJ0$?TjY`9G55x z6@>M;J=VZT=5C^qK^h4O>K*)GG^xE`fF!XpH1Xn3$zx(s6$Jo(Ce5=Y;zlu`_qo^ zM!Y6YWTv1ycy_3udv<7~WQfU6yai%jJU&IBrdL>QSXca6qFS1JC`o(6ePMaUp+~xA z54r9!S|==X`Cyb^+6^7Kb%xeu&b#JdsLrtyuBBL}9@Xj_CXqQYMM9=9H$DG=%SmU5 z22r6!kUC9*Q>Sq}O_2AgVQ5-)E?T-4}n{nqDaytvWVYY))C zR4n%h_0X2j?zn|<6SjtN*XMGq0+hZcxGm9#U->T}!?21DQx!~cj)L`wa&PMbf88~)XAC>T3BTRD-+={x9K|FiK>{@Y~&%7nXZ z0mg5$E-Wple$n(PO#VA{9ykWyBdfXy*3uZT8UM>5v@?3l z0dHKonCO+1&6qP)Gs9|CwCFcp_8bpdxV~@!ur;-{^hpJ=4d11x3av?04X`VoThCJ$ znWBa8Je;jn3OP*ciQ6K!o%!XaN5O*1lnnT)7KLszfT3}+$}c=>+p$tv=?p9`%4r>| zcFUx@F3s5Ih7Hr?n^_h)Cu|+(<4|P8HvP=0yA|uL(dz~)IJ=n6cuxizE`#F@uSIc^-A#cz$@-5#&a3x7@A0lUJf{B4Ap+$4(D?_vcw*6MDo++cLZSoe-V>Sw zMBxVCD9BJ$0z z!&WYeAt zi+iK%=az52-0NZ@y( zb85#fOFz+kDELjVivCo@>Z=@e@ox;fiS8dj_-WUauUWN;VCgZO%*yl#Mz7nE>mT_M zEGEqye{H9a;NxzH4RqjY30j=7i8rBDUC1DmjG;1u6D*IdttDbFh)wr%D@tfQ^G6z% zn_q;VY>xz9aElg!@dO?Wkt%_sl*~^b@j%WE8txoWp^l^*bFXG65UmNW!n>z8EiV(LVEpzl!pwFkx%a zckC>{;_0yL>0k{p8)^`2nB3k|AmFi?W5hi;)dQ4Wt1@xB^)Pz0Qe6!UG>g33 zK)!yDQ1KuXi<+tm-X(jc$5r4K&*cbNkZ-*fV~*2C&FHkZvsm zz1Nu0WgYjm)wiKJe}l1-yIw7kTvm-;wgq zqF+%!1CG3@+d(GD+o2=3=jFf>@4N!sG=;m+sd6s6i>tw)#z=QaB@=zOP0jx2Ch}Wd zDTxY=Aa25`RW|#`=^;9MqZ1TMwD1R>22cGn=MNsiMXrrq{-Jq`OAB*tB|5>kPNf+> zJu@nJy2gC?Gaz<|Ym)_xOC5gO(*6S}bVnFk?&pmOi#pank8QmdR^dR?kcL`>fs)o_ zQ%_6-FxZo=a8DO&;M$);d^&WRdJo`>k_C~W0RAQ2KGr~Goy2oz4zj z>N8{o@`Ofdf`z_vbO3Cj#0_qwu^q$Ajn1V#G8rH%#5SZ>1?{<^-qMLViAFM`SdyFf zT{Ip!CfBv9s3M{-kJW(+Ejn?g@vRQ6q)B03UT=NDjo88-$-IsnG}-&wQke&Zbi^Z7 z$W)k`NijT0sJ07w06nbg+AbEz3F1hobdg3mpYJHj*v>S&%uq8)Q);~-^23QQdhF;kPZ!Nry^!9dmKiaTqEusQf z4RrMEHJde-X>;t6k_GDlC+^qu#%%6FZH@^5*Ubk3l;{4kFHt2`e^VA;tf7=cC?9Xe zB7IZ2Jl+-V;=QU4pf6z>SH35g;up4n+u-)Fy|Ul@{XI+n&E(7~4Ao?J0jRvP9)~g%uH`w+SrR z2$<4Q21poEvN?9N!dq1ZC@Omif#X0l|5CKhuzh zg3hfJR0CMxGv5kUR#sl_S2{X6eBZoZIey?il7*vrz!gZ}68AFFbO7cxEYv%#9Fi|I zb;?aj59qcuH7l2s+%TYYnT%Ad7FEiDj=w~2pCLMC8?}{@y0rm^0_cRbdg{iXN#XOf z&r`O9<(Y7dTAb^(Eo}@IU`vXWDleA=(30V*FQKzBp|Eb*-AfOJlE9h&VqW8`&j9#{ z6s&%%-p!hw%*@CYIQ8f@=Odwbtz5OQ=1Aw0>CGX~06sDjCBPO(Qf4P>DWbHLxdK&N zRWS=W{gL?qvV|<5ELv)88z@???nKGfxR?r3{4qoYKVw-zI@UqUR!No`vvmGedJ!C> z@e&#;tQLE(AK}5Ag!Q0Ei~Ts(cks9^6txj(3=EbaWcM{rIpJwIgi1mcSXlqXY%lG2 zOm=~Lhlf7CNS;*F!?=G5DxYK%Sw7gfOfsyxs@!*eq#3^bZh<1kwA%!t`a7y*xwB&h z&9aIHU6uW*xIsdiE9sqfGYd*1iR6`cWrnKA+dP@u|GL?lL#qlTdiQq~ZB@p^DD@eh zI8=!mSzm1h>WEywOMgJuZ}fE%nFy!K5gc2U7Sj{=3aN75bjk_k^}VRr#p!rLBP3Am zZ|^f?5P4LxeZwnuh^RBk<*bEuG>8@4J?I3gd7TyIg>6ggaYd(%aP4VoO>D!tJ8BpW zY>B&cREa-%*2BV9E_xr}@R=~T+k67(#)MQQB&Vfk;-qi3-E#(Y5a+(BI|N z66w1vL&wP5J`YYByVSrd6`@YMJk7w4O{*5zZlPDrT<%$FLAG{7a&_H6Z}K*OId}UZ zjq@VbCcGi|2T28|H`>iVJN6y%|85{q$wFx@z-Bc9*sT8Nk!Ii>5ZIa8+1fZ7lL|XH z*gE`UA4&Mj*EaaBDWN&?VQi!H$1r#2>Nm|LUk;feJcjn9Q$t&Swb1XfG7x+kWJRsc5X;A-->$E&-!u zudVG2c)duP&V`m)Ot;34o}glSgi!@S{AzGFBR`kdYfUYM`Mfsnc?a2pv!?DF53FF% zs7i(R3omH0iH=Lc^z{0FFk2A?Ap?LBJmcl{+4PxsorYejDynftDUEi>`9^B!MMxl& zF$Os;R{C(NSaAiv{|IA`@3($6Z#`88y4waA7j~WHR;8oW z-ha4~69H4HaSC@yO*7g@-@cyD%zLE#qRX_--pG=Ll;4aTh_VDDTV0Mxcohf$#tTut zZtd;331IW84%s6aU0)Q}8E)+(+00lqz}vxM$I%|@*IICka!q6-zuOIbo$qxo%J0DU zFWHOcKgD9by@I2Bm7O|eI%IklXxnP}%gly6;8!Pff@a?g$rNUF7~88wc~B$9%)iXd znsmt+K`p?2;}-at>yAo=>Fr-Uo*xHkF|7b)5bz+K22QTg{AV@qf7ii3+tm;JHC6{G zX?mbCVEAwd%Mr+}7u@{22=GX*A6W67Y&>^Ido#k_ zX}o(b63kjRx2?4dD4m1cuLXAdC7jiYgn#X9GgmR9L9Y!Z+y}5!lC_6hB2=}h^+a~o z7g;65p%U~NT!;eF6Sr>OQQwoofvytpuwSVrUHO+k<3J@HSNg*`oTAJcxs4rqv@r?R z4O1?z4CNJT$Hx^n@Mivc`G3r1rakhaAvqtYo(d_v@-*03eB&o%FHi#DW^d2xbX0m| zy;1GQh6w&FzRkV(J(%aH822!w*I%@exY~ytNuf#CCa;K}HZ})L!`oT+3(?33sjO2< zhkW6=KI75MU=HRJZe`P<4)v+Z4no479dSb|Cw0hlqc?t7Pof~P(W!zgbIpnB5ETdu z!JW<}X^~)S(eEz7G%2fSJV#77^L7i3SXZ*2!_e$R=k}DC)`m4nSw~+!g-T~U1BMUZ z(=>-;eW5n44|QuM8OuFB1Zf;DCek`bN6H47nPqNkqywA@sZNR1tya_j{5$1 zl?V{`60qh|r`=YxSVQ|UX_x&B=}l8U$D)}}H9z z@p?_4DDE!3zMj&Ma6x2DQK2#8-z#0c1wXe&`&!}B-4Ym?d2%n9I*Zg(k<#n$;oVF8 zFz##q{W(?RCrP_6@KoCaYV-e@cJcSA22?X;4J?ceok)T3XD4H~fA+}#2!aJI)EqIW z@eiSVl&=>y-V@YC0w(88Riw!IBk}<~lrD!ZCTpoEPZV!|oozfHQ2T)u7gVWIh%YV^ zr>mY59j@o=uTLkpkU!{n#tp#o5ftbLVoXv#VlQD^EZl4@M2V~6j!YHAUo!OT)wu9P zA$AaI>B%>lD~_ADge_xDS?wQVF-84MWr_9MUn!R`i%^$4WpXPL(Z7f>7z;>uQLE3i z?h*%6K@<~NHMq*iQ@fAQU2MY?VVkV9lZD{fy{IgcpZ&#>O*JUo&EC^&s8NcP2DH3J z)z;D>6vj5lwaZCp+K?d+??bkpr9R*jgv;zUG?+{LG^i)mk+^Ckq&(r`pGcNCbzWve z{$dxWKlH-2xkVIh{J{HF>UR<8n)CZFTYusSiq!M69io=~SGgw3*1ZlCiN4h^E_r5^ z2Uz12dIY*}n)8{QNGrAJ>$l%86Y2ew?gMMMm(?I8;R<07WWEeZ0&j>+(K@gzbI$Sn zvHJFmQVNDOD<^a+BZV~?{h&NfmnAEU=zt#eV+H(^Br)p4CXaMTl|c%)FX3-r2Yq(& ztB!LS!F5kmD3*DA(S1n>K_S+b1&(sJvPz6>uq2+nd^v{F=JJ-dIz%Hvh%woW~mFV$S+Uf&3Z&i5fG8!X}%%c z2eFf+tBfzkWW)xgN;eDV|e%79H2hc_{MJZS8K=1#1j%%11 zgzC+>Me=+$R&Xu^d-S ztV|ZoAGGEj^EM&iybLDy!PwYS=S|zq&cU?nr*bv%e8>(66!Pa7BVgDN^ZbRe9 zOV2diF#4kFog!de%jf48s#{#KbgUo4G0FP#Fc=_`;=sX58aO=3FAxIiD}Hr!O1npf z1ii7H7#HH2^^@?UNy|9~X?VJfA8MeJ^5G2AZw2~yT_@}aEG#yA=w#W#j(owzp9;;8 ztKoeMnt;@dHT6V;^>ZO0uY8Jze1NH&abeS$zZ0)Yx2;tq?ZaXnKr7+`q_k{Ad7ZKM zW&LHbe)`*D?fRF+8uLm{$ZtNTY+vJN!Yy?2rMqAZH=Xc2%$V--!J*ZWbxDVlyj zDcA?3pCdgFMRQ{R%*{k5QODyYEv$z&d9F*7<)K zh54%!1Mb})Ppgi9hiypN+L-?1V)D;?0SVtEVl_D-G-3XaVd4&csRXd@ij=?O1^%&j z|0B*``tO4O?GjL^67W&*Pfz>Yj{B$4*%TX}t+q=8kR$eEs0`rL0bx-%Hq98VB9K~F zBpfi_iv+4r;9bJlwgPQV*(WWIK$v954yfeHA*TI^!3b^ z0V`G92|#rb;@T`33eRz6#R=w<8zL^nw2RxL;%Q&#V9Z!6q?{O*G62_WmEP2s^!EgD z+=njCNSg?G^X!LUMLOKa*z|>lW+jh0vI2ZNNMYH520GX)>*q?<6Vi=XU+&665!KqF z2+ask94GfkrPHQhIua+l-*%A}3eM0AX)5+6P;w`Y_qG^YDk5EVzIeBdipr2JJujO; zswHEXI!m)@`5B0U+>|FnMm!YYt<AEURO@F}V zci<+jy{bHyT=@exepPy_{uFNkD``@gJJ=ZztvO~%+ z%V8;oPZsnBU9UrwEEyMzr}+eNpPGO?Hl22cGiaZR&{2}NT!#*g%ocdA%U1*n|P1CtO|agj+*NGZmHM zZhMu&db`rhrE_9cp}BKiOFNC z<((lA)y+xx1rSu=$hRVln4$X&L zh&`}DkFq{jY!+iVkWjPyE>a-~OoI{4no;>=g%rD|=Uiqr(@y3cko^a9*|Fg6Hehh_ zjWXJm-8|5U?5_88waNW_bhX74=zQ(}@=2u{7*Z+-u}!Yi%h>z)`P+6Rc zhSw@P3!$honi>!+VvC&Qmh@yML6xh`ZK|VU?_#Mj`SJ8CIvbtYExH7$bQ%*!YsFEH z_DQ!(H+>J%dhiC^{0lD9yUrZx!C3!eNX%>ULxi??>3 zPu_1k3kFN#w-3ipVk!)hZ9|}8(LF3f^|Y&KMeUBKw5O9u^+-XwRprtUsKdQfkhBS8a5W|DGrjuslN_cf6bm09u7E*4B0PTWa)q zWVUg=EH}B=NH$o;UOh7#T}csz4^&pH>-c|5zC-s;Qs5RDE=67NJsd|t?Mo;SG^Uxl zPL~F>IpHGjM^E~w;sc2&8MT#Q=)YHQOSZv-A^o7>l(6@8sgyvS0l({{&DrZC&37Ya zSs|sbQ?hdOnnhPB&mPRJAxI;RJ}>=DAq9_Y^$|`(V=a0{$5z|Re&5^H<{A%Y>a_v%&PT4Rd1oE>_e7QG8rkjNKOc^J+y+KV6(Bx)9?^VZ zTb(5!bo^c|_(;qn-%YaYOyMhiBKhY#uzI6#z-He6W!wJHhQ4PFZNC9Kk{aNg%zwU3 z{?E3e=mgwd9RJyr{IenXM-VHBUo#36$CVF1Jf`|*^u%xhG(U}+5xK|BS)>8R>eNtf z)UrRQzCF~Hwe=$(ksh_DYk@1|VLW5E=T6zPylcF#C&0JOPy3fVkzg7MVq9jzxPpto z2l%Q<D38n&x9t`3^r^tCZ$MtS-EmGBj;V%zacn{PD#&yvw9cila|5|!0j_LUiJHVtI@Qn#-aB09FQLv9M8 z4HoW-U?&-7JzmGe4;*fUz3@ZmME4BH_q;g7p)9|D4&}Q z!U@k*7U@S~=npOA&?K27@_%)Yx~1TNR6rXhH`GwA8e;JZr_4cxYiJsR>bO&#Hm)W>F~K`v<;RhRV#~Z6W;En<1TQ@sQ&NgBY&LoVvVH zdHbYvLe~N%6BRAv>Ytx6ibE_~Z%tJ2IcZE))2LEYmKM30MTkSNubD*d;S1J+*`ao6 ztklc}Im6Q>hqT->x{jBJ$OmA-5;FHzxaf4NgIk$&m~p>gf0Rq5F~7j ztG02@9Qz+ua}=D;^o6lp^A%Q+$ZyY{@3Sa10Qc^t1=>bt<3>$fA2VvhXss~@DO}pc zA4`c530yJ&8IXJS<0V(`@b3Qcv#TJD_hS6Oeq4bEQ4ql`vr|IgTG`f2suc-yq$I+# zLUV+VLRi$W(=grA_cD|KRBUzMLB`mtsA$XS-C7-9lH?*dZE<}hK{!z3PKIj@^cHWD zGx~9$l#|9)lk!_ABKJmi6OQ3zHTz*A_Gb+xY>V&=-YQgLqHzsb_sk^AD zj(oEA4d1RG6pf8~y7o~gy9P2tu3PG=*zO$yJa3kg0UfPvxL$lb9NE&W@VV{Pca_B} zlb&;lnM}UupGKA~TeWW-%Uhhw=+0B5>-7gG*NyA0$w43MCzujn<-PO0Q)<>y9K#6< ztv{{;u(YA)QzW5(sDV0A6=o3@5r7T&?HK%B_(=fhE$jkj1f3t_&-$qYav{9P%jUq7 z&ddipNY8it0)poSy!sej@cfk^J#_nG=PVpUF)I-eu=z58By%;E=dg18Y_IG3bwrw$ zfrJc^)q>5mu8pkMBm*Gu;MKq0A0vq=$1*=A ziEm=Cyhb9tuTpb}vt{6__K^eh%U^O`)~4zc$#0<*d;_AiaIhn-KX5(58S=*~`Q!Af z1$@e&n-~Mcu(#5&LmRu3c6?iz3RtBQbbuZUs?DjxLyc;BMui+Nvykn+1LW<9j4zvrmG~j zd5>`kUys;J^?f+$wd&;tC&wmVuFY?jMjct`)rz^;@D`wZyOJzcRAycEt=%NR$?Gh_~TL zkYyFE!N*qE*NQm9IQQ*1XNf)VF46v`6W_nUM;d#h6Iw_Dg!w+UXJGFdE1zK)nNUYK zy9!=_MF*jT-sB&pnJii9vyZ6w+O!;b=tt66XOhRNCDG$IFS5S%lO z;nVB0f<@Oi4v@D$v{h?*%qCp@FoS_NX({z3m;`q@^T+K5Unq$RAlD~=CBV?$`Bu>Q z$Ut7|au;yhynWa`z1}>)^9+ z_@KR}#-iX`S>8yaflWk?f3)$mrx}wLuMmyteHG*e@FM$BT@1@15U*mWW$p%%xbCori7@ zp{N@uhxsBhecV`eo$uDtw^UB)ZQhB`?r-^?kHwIGJl!Rm6NzkgWXLbJMdOUQUPH59 z9#cDI6bX&F)O)}Pwvwgj4Z&sQUcmnMp!&E{mTHibRR9mFRiGNh`u}=4{_9zV_6DKR z_yJZd3Hb%Csf2-yOqW9W0SA^-U}#TkB>9WKQ}=(M*^|Ja%Vwl4AT&Gm>xQe({wWZ^ zvkCdbn6_{_KnFGyF7D8flG=9ge9YOZQj7kn>dg7L@%IIkwXO59roc@dr4?pzAH? zCeA{GC(gWtLSSXY^eO|U*=VXkNhC|j*Go04)&h?6p{jk9I za()P*IGRP}m4z=}=g_|ln-Xof?r|$gw@~7mN|{5^=LwmVTnd&hSJ<|!9rN^ul9V&s zl+V9*^KnU~6bZK1nbMNC;70do#d|XOnT%FhEGmuqkQH2lu<|R2yi#3@5wSlw2|wv* zS8(xLwQx?dd=Ass6Ev%%_rI+V@`SrNID+taPnN*8=2=(AEGos}3c?12a*7e1h8wHk z9rs${ATpV5$zPt{z&-V9;k6WN5KEMUw0i@hMLh|bPoKTVjeF6#bXCgsTqWKY z_DMI{3$YB}&Tl6oDOH+JRPabju2b2>5gWE0D#1H+nJc1$gaO0vFu!|P04K%iGe$=^ zI~cF?ytgZi8s-%-c*Sd!fI9`;W)7NTo9wRDLvG&_X)nLOCR`U*A7#3aKEY3x6Q7)!Aymd><`a@mC7l zfIXT-Px>QP8kY3q7U-kgK$|t{NG+wg$;B8@yXtT>wefxb`V6iIE9-#Or3XO;D+mn5 z2eRUAUbGg@T<1Sn@wbW}cHCaQntF~1S^&$CI+kC5bwN+-nug_X4dmd975&kMaeYa% zHez>4j)c<3Frfjy2Jdf;dw7Em2^F>?%lR1Bv6uA}YjR)$I6nSKBxB7%Ammu&$30fr zadc>s_FExN(>+Q;X=F1pwJv_t4#PcgCR9FM>3J0eqvMd1tY$^<$s#Njm^;^3&c1)b zpm~=KQrtI^24MTLiaW{}vLruzxkqu6_R4xElhy=bE~5wuHg5NpK;D!>9HhUL(lsNC{c)UFa-{@eS`g7|dsos1&;R7#Mks5{vhxJ%UXmw0H zU2x_3dR-VQ0UM!6O7;9!QIix}atvZs`LikX6`h1xH{ZT_DCrBJGAxoF)3gpXE60}E zj}I94F=Bd4Yg`&x#bz)GPrNo?`nuZR0k@F%(lJ?Wmyt?=sHAv{a;o#h?ivY$h~0Us z>w>s6evF>Xrh5o3T58hP;Qm}-itJiC1AQ4S(|#k9u5sKiXe~#OUW#bD4c4-V^DdbAg$FFZFFE zNwRcOEWXAY^nE4CSJ@3GQ%5Y0Lrdq+&7t76w8sttnWVm=`<4+_WHFeY>xEHMN_kU3 z&2n$Q1e)Ydp{-*g?ea&zF^U*oL(P8IVp=KYOv~X6Q3$SySixuQrH(|en57o2gLDfV zOnLg3XvdFzzCPe~APrdQ4!}zP&xjR8TPuAVeHCK|$N$j`BbEM1&edEFG7zrTK|(7K z)K97ONhu2@y9@qRv{Lie4zKw4n7&!h2hoT*YfVLBw9JUb(PSdyCiCU(kMk{P z7Y0EgqyIFR0mcB5Y05J2ZSB6fV#T)XrH2XbiULSeQv^(V7&&w;uJ2&siDtrC)d@+Zu=(gQ zk5(#d>44VAK1)B3Ug`;K#HrH`heEDdPk%qUXM#y738d4EC|DA%j&2=Im<-=$y`_ks z0=SK*>9hFa+^|ygFbbYqi{dnqQCGQ?XStCVGOxhVXc4x^N z;xpmm>v?uFYjBmo4B8_dgoXMXoW8I!kuj;^#BJwdW%M@!3RHgb#NG~=hqcXh!vU#Y zvh<)C>~cXqp!2(v29daZGKputtgPr&>thtkq9Bg743`VNqJpcF#AS7=@bl>%q5Pcc z3UC|uTK6H75}bEJDc{}tVb-}ptZC)kxdEnG5ff_23y#}_+Kf797ocCG3!+L;Qgo=C zr@4TCjSqCICnUrD+q9 zgQ(ONKce-}vdl$oo~(8vS4DLjVtlZbPg|*C#4sZkDR~e*%+Cc!Pq#78Q#I3`PstCK zn(JljJN*6*zI<>rOg<74Rp|x!f+9daMSz&P(=5|AkKP4Oi(=fp88?@6txC#=NTrE9 zBH6K+PBbM&I@QN0xBu(==-~HsA<&lLMB9`+Ht#@nJuD`75PN12d$cFH{2z&OY5I{1 zbgPA$VKNVwKWO*<{Rvq>no#Wz@Ln;9`QO;Migs2?wwA^=|44@XP|5%9Wg66;ba4mK z-w_}%=qxKru%x6i`ud}~25M_iL$2h51Hn|;qiXC=ZZ!(P7b;xP&qhL5v^r+mjGALqTg^7k^{4buj^cJ?P-L5#hPo2par++V88x zs+Z_50xxZbap>&85_a~Q{F+l<|L&h93OgU@+H%pGLhQ)=b* z9=amzK}KZCKLkWskcQRo?U)l){Un9ObO};{io({@@V=g8%1NW?8qif`dm+ z?>aPWVP(!$>ClzO{<5-?3uxARU(m;g)z{-`bP%GdKvP3^6kTXnJv?$+FRf3>b?5~Ye z)$a^4eXTtW=`#}{3u{$HFs1OVFULTv_il-9Ds}oG0(ns8XdQYs-FWiOX~l80E6JnU zsRZ4#TD6-G{^g3*uQAUzu81Z&_+$@`m!#S!^u}KvT7X}qvYEdZ$_CBs7Os@TuI4jO z9Lo&(5pDr6?jpm?wCcii}dqbxD~R`BB|zzk31saMMmxZH^vTli;SVDb4)gqCrRAwhTLBb zgyxgqbE94@tj9=YG__hAJ%Dm(-yU95T=An7GU|!1`Ynp9VV*N$GY2EC z+01;XXlU+bILZcIM33@wJreDHlY#40wD@OOc@lDLt95uQswuM~0<6@@cGp$LFv}P6 zkreM%fwI21B*Ds-zHxx{?%@n8vL=t|m4T+^QEF-Zy5jLpRwjrbdV8Ff$A!{OtHveQ zndoR@SqdH!r_!)dCf~(gOE^}40d^Ut*k%~ z9^jZ`pW=jqg>9X0(CRHVd+OHtq&szMDrfYsptWoFa$m~$b#vADUqVJ-tu?fEf4L5q zMZ3VTv%D1;jyh(SQf*i54{*!&f3SS~#HV&bQt+uCM%e>;Y((_P!Ob9R`zKdnd(4L$=%jSFaFI1j|VKd%F9#I4F-u$-I+^c zaTOhcZqOerx``~hvzN|aXUDKR!89(V{mx-9eOKSlYE^GVuFh&7j<=~M*Y5+HLtus$A*2`p@8uz+cJG@=^7voGtVv>7MfwOt<94@p_&}Ng0!+M zx;+_In9Ws?3$&R&t2b`u6(39;H4QH3m}7P93Ac^xf|FBceGjS0)UN`IK^RmYjVH>WD!%7Q zxwk5}kuNu)e+QBUGM4Z7`9$zH{s@gg3;zfWX7%*DPqUsai90BM{d}lPMZONEhuzmk z6m!f5h_9-<%xDfwUa#g+<9h77P8@}|T~Xn?^~RrN@5IrEt$u7P&T!7k;H)k6xv)Ij z!#6s5jT9f_LWd4zg({Mw$fX%hQa79X9v01e-z>HN=&bE%(nnwM5vq;i@6el|r;O5FZlq2Sc$p6Px*0Sx`zci4;I#6sTzip^XCSnqH2Q zdWE1^u|ULKUJt4b{YWSwm1wG|KSz|+$^nLbiN_Kr=nlHmb8SCE{<3yVHBtH7~2G9|*iCPrbpuAbKKh#a2J0_AK%6 zeYq!Kxb5s&XBgVTeS2uS1nb1T?;Kpe7&72Mym)=&eG@~BQhW=&#@oxL`jYbpc29le zmja*I6UWG}o$N=B)_-R#EhjH`_x?i}`Oo=Hz{fC4V}77M>GCh{?2!qYA5`MO_gM@N z{RTC8S~q@h>(A=_ZE|qz{N^gswB3-|MP~*0%M){J=BS;ax;;W4VShfKz9n2)xq@4l zUotK_PS{SonNGYtx?kdd|17H*LWmN6G39E4}u}6)8^b(w_L+3&Ez%d!mYe=>KbU83~w7YUKY!1Q=rnf^(Mer9Vh$M zn&^xKMFAYb_a-6;Zh|?&9f0dF&MEqo5J{u#O($$~K$|hhDp*TDW+GO2D$z-2sXx#p z9b?Tc^zwp9r`2Q36@5SY*_%4~%f6{t@>f`(DSYo^XZb(4t_@ z=>ir-^iotFVHK`@G%O)$MO`SZi_&A1S!T1c{zC66++^6)uo&YqJR7!c5Y|LBtR}x` zCdRE0s=5YDa^lWl>|}2p(QI2yeB)Y;NCl9d$2o3?=f<1#!Zj(|3PoWT7p|bM)n~(! zX`xh!5JBe$AR37!Ixkj+(H&)fWBaaq1)ghqCuO;Vo$RUuGdsn`;HL~o{CuEgrwQK3 z^Y9}7c=M)7S?%S4_n^=m4QbDF%W#O?`zLl?;m%1huolv_Q5f#*oW*PCt6&sAF++1% zLmZk~MUb{BGxUoYY}X(+~7otswS^O-hH~juh_A|8dYy&r;}8!A$!+z(mAf z2Ht;W(Ekw89?Bp%XIK_AXRIbiGdSn2QwFW>5nXYPUM`)t3tcZJ?J*z?n?KT^@QePA z%SQSZeFHa8y+<3*no`FddIR}it>oiL>j?Te%@!!!&jK6l|Du&R+u2#U|Ep9VsjTg| zB80|!vZS&d!pSDBiK;QfPUk|2o?x3%PyhgqVk#U)?=d4NdMTjrCybl>2o)>HLzutM@A-iy%*%BCybFK3IseAu0ecOwg4DhS- zw4>!2m(x!4n>&G1th|4ND`GOtH8I3s@3lsU&$!e%>YIV~%Q%>7CV_gXyq zvMLKEC`>c%4Y9xiOTR6bI6M;3DNp}YGTO+ zqCjw3r*W@Vg(3tnOi zANR{PeeWL8H)L&eH?4QdJLGYLaYfzbN}Zn^;`CGbEWAYTdvd3vY6Oo4Bv6!Q8gW?q zRmA|AKaxEpv4InE{h~8R{nUgyUpECuuBCJlK&s+H_D5SjRmhw-*`#PYi!C^-LKskB z6NH#W&rYBTsJgFi9K^D2(^{eRfSb8T4Wi2HPJpCSPXd8$c;wE0uq+Y-vV5H4-B`iyUlsHlo zeii9IU8bhbPk6M?hHxRE|iI@X2C91MSh?J0pI`D@#Yah z+PeDiqL5Bq-2^&fyLezvOL>;as)6BxZPO7uis7TzeD9&?LB(RIRjisPBFngFSkZe%bu zDDCb2{|wv}!N-nVa3b>oOFxwVUE=>o;Qq4_j{5g)fPG^fn9LALO^j_nGvmzyY;Qn-$dwq3fhA(_pd`x&kmt9-R!RPF1#@8Byz zNoE`3BoP95(AV4aqQ+zJYRu~1Q_+P^k>F(ztEYgiR!P@1-!Fe-Yp{FO+43V#uT_UK zz8JbGj4E!yH)CyXonkz%EY~j73l}O>z{AMf_hwxb9a)u7S6q3cIFcpImW2bHo8VeH zGw1Fubr>AyFk_c&&t{p(BAxk;Gfvz{=F-eN!05xsw8z^}p{RMR%7`j1lO-6d3YaBa z$2LFG)$go#kDxDXE}#FR-A6z=z+8*pw0s_#R(aY&X4q6Ur@vAl?u#YoA^(eHvjdL5 zmP})mbA$Q_ooW9Xd7e}=2`P<|wt=o8P|@Jt7i^eYgJtbpJmBAYAQi!~RwLti)w!4d zu2#h)-N94ZW+|ME&wYvWBfQqVeguq4obD^liTbBQYc&nr`=p=WeU}QJerWn|UpEBL z=;e7rnQvkzUfKy1Rdpn&(w(_F${i-zm5^(ekozkOo?h_M$&)*A1^a4qICU;|zyg}{ z0rrh_E2Oe@8`DS*)p-#=ZTR>m1!6pN2br^(S4KMH*!dh&QEli*keB%@_g_kA7erJ6_`evtfpA z#D=)?*7T|Cg7%~joypk^pTn;%xIc$l8!0pU%RBjn8UeV(BtHaCfxVqjzF+?%SHRqNP+Sk6xDOx#(56|y}My?epo5=IO zpsY0}`zmgnyBVfN0_|dpJtt&o#7WaB|i8~qtkg8z3 zf2Y(Q&-6UmjGNK-C0LCU#`!VEGaRKL;!Hexa)ViaJUK1fxh0lhTL=HZDJwTZ)Ni_J zJk0N_YxHi5)ebr%8$jJ#0yELA*?TXQ0nfU(a2lZYplNm@3n|dMDd+Q{ns!0pEYY8Z z2`rL&^(pvLXlW3>aDw+SY!x+*7$&{*!01}pYue#7+A<{8r8uho+V8s9-FQ@K()i#B zKqjmqyCZ$kSdvs51}x2VoRHgQs$>qG3l+(n{;<}3O&PbGX!sZWA0n}JDo?cLni{|+ zlj(?_Lr1|~i(BU1H+ietin<@n-OMic#563}39QRdZNJr180vFpo5r2m_i`TXucI7| zlcEeGUA>dAYBHPByD`sonuy>PuTWlQM&tR!=VKWr0wm7yu#~sko(x_p zVibk6#tbABuQ2-gwvQ%g!fW!K!!24 z$Pdt#xkJo;C4)aMQ?{Nv4N7nOCdif25U5M)C9u!{T2>1R9-+(Mi;VTuD|ESPq^G}x zGyc-D9wiwa@`&_L`HJ%@X?oEb z-y9{2SnaG;aia5Mw!1Mh%83U=%=gglzoE07-kA;0fWwIz98S#tHD~-ioc=ZvM$nV} z2kAWT3j<`ty(2^*5VKbJA6TEHT!5YB@dQ1*ka=H7 z8^{%DUmm0N6JQPD-R+XD1a6>qg5@cLg#N7ire@7-cL?NmJpYv20#JOY%5=X=65Uo5L$WU3-; zIz<|In5Om=+7CL=WP?`28NL=&zOFo<`}Jm-Ex2Jmnuus(oR;1Rsz@-`F(H~Ji`NSd zbVK#-N?_!8`xSyYS-Xi8#-6uHGCL5zO4j*_CJzC0ZVlVUFfo@uyW@}H1kHiG;UCNV zAt|lrid+JoG(%tk+0m1xCfYX-N#&KoDI`iK?Io)GIx(|fP7-wA-=J8&Nx=8>qkQGC zhSuO~Eh*u-0n@RRCv~@%xrxUwn?*gCdzqaYXxe2tOaU`1)8d`X`H5NNx=%+7LHJEF zzI?;5hppy^KjmS4UaZ;`Xp=o8eMb+$gme~**o6h{pV54E7Pc@=5xGC#3n+_UGu_i= zOuBD&z-;O&_X1@q&ijMBF{O1W{L)Z8B0q@@qUZ~XGbt-&@JOzHLnWe;H)fYy9n|(S z1r|$-V40-kIigPjb}hsnRFasf!jSi7WOxzzihzG0y{qM_yKlWB`?1uBWLf`b3p0f=J# z69t6*Pbg_RQ~>$c%kQ&nD{GdDAB#S}tUtjUp^w6|=S+)^Nn)hoE;rsId-5|PPK*pB z4dH_JEx~g&SI~f&O*^!69T<~t6+F&d*7Fr35;|IQx3@8ad5Fh?3w2pXZAG*LtK~42 zHSUAgFcMYUmk`}u+$=Mty_ce0Y~unl>;wC{+{|tSQ4P4}$*FGw#GN*xTG+B6LQdZ4 z{;7iZSr~xKkTL86G-$LU3^UJZNfbtwI?Nz%wcHfNq6vA{073l*r~UyAeZIIQR-U|$ z-u680hc4!nF-Ev;mjcK9?e$4)^tHgD;Oo>YJhko)qnpkbgJ()Ul1Dd3WR}kDHcei*{j?1dvK`wqK zosg-;EXC^8?0l`d3}_Uq2+^e&c`>@8_!+7GYz+R-SUO98Tk>p?=SNw%vEo<@T1?im zo@Cx?>>zm9ZD?(}Mbmp}?WO8FPHkQX?|rG8qL8@gEDwh9HPa)|=zI!{w`=OW_RF(B z3Xrc+*JCR}_X@B^WK)qd1HvGW9E=b`R;vG4rKsh%RBsx+JaYQ14jA>@Zyxg%MKMcU zW`r5!8b=%CKxmGBc-kS7hbHY6aGdA(dTh)jO{+Mtql-AAMK2o&zP*#O^xITl3=9PC zWvskmwFcAo*6%1-%O*t~RSsH;e)b(uNVPVBl8d~%18xDP-*w0R^f3UmfTVN#qLmURO z1&88)$I<;wS10D+yr7 z(fvb(smHY_->8k;5JfIx77feM`4N|-^cn5&6!q`*N-%nvKc<5$ zK)m)%B#l3AhdIZfF3mE4diEI-_=Ii-DMzwM_F)}1SP=VdQ6Bn6q3D!q=&T|g#qlm^ znb?d=O_6k1#!P3UM)t1N#MmEMZYgJ^YU2PZ%d+riHO@$jxXZ47as>%vE;l_K__vY} z36gA)e7>i)*t!yQY9!49N^~x1_?! z(KFPmN^7M(&G{rYx`Im@0b8gry!zyDFG;NDiWKMfENAn2NHE=`eP5?66u|-ap||TT zv=AW$Y+tZ*^XzKOIhPh~l5(y!Wbt$$tG=4c!a1eUMqye}UHXB{nZL&raX5!m61N2f z{dmOQgyEoGot%x|Hlefk^2*6Ofl%)2ev|%9(77UAy~a?;+*tOPfF{(t-vUUgBtHM}OG}`2ssq-WVZ12M`Ozi$V9lr<>mF$Rl6ssxEx9bRmehqs^d5nh zZ151D=awFq{+PxC`x3lu0TVb>@XeeXdEZDEdd16V~<1{g$Pdv@C8{j0<8|5f*zKK*%y1l7h_U3c|`T z2G)N~Sa-CenG6Su?-Gnb3VGOt@3R>^vW!-pQ3NIc**K6T>)xd>)qCJ$*5-MU+$R4==IxT2OpO|p9X(F{ylD;5Gg~@Kwg4>@vvRjjnw;azrslYD8hK=OGdv($SmX6$ehI{6 z;66h}jT5nJLaHOH{$O6L`O!g5O7#>sbL+xCa*v4*eJFq4#KTkPYWrw; z7;N>Zx{#3>oN{ARIVk*$hPwK~velK{fVwyPtuLi=*TxOcM6xNI0<+PMOB-^b%v!%O zDY~nC!S_wX5zBQ7tzHX)q&Xt_$Z?!{D#prK5i>1st@MMuT+b2w&c1;LuyGA82c4K3>kal@&a1HG5Ntw^I&-i_024r1qJjGs~< z`rheu*_@f~2)9yHaSU%%<`F|+ApWgq#sUSNw?el6@3SKq5L`}3$i6w`qZ37-1hGF#KoZLk&f4J<&2FG5pho=UVcA z0k;yxCl&kQJ1>rw=Ed{AaZjTNgjt}6WrbtB{ER=;C7qsi&dc^eAE!dkjKEkskx};+ zR?l^*_30n}cm;^Ew3dI3maA)%-_gLUo=qvd8t|uocQxMOWmRj^WAXlHD7}L*o37(d zd&vNypYV>q-E=m?q=;zQP!6cIgzW8aN3aGRUa&Xd)^r2hn*Mi3uK$ql!ANIUbF;q` z;QvneB=|kFI4V%!gii@qk>dgzO#BtA8xn!2VkV9JJ-wa9_C(PCP<(2*!h%M_dwR!G z#m~|71yJ-G~hhn zWE9iOx(H8*({WgDvPjni8?msrTW{CxAH}2kfPT;Cu{#*rH7$>OnP|$IH#vu;pU>zd zdftYR-bwt}+)Z5f$o$7XoOBjdF&RxFnU#F2Dm~5(?pC#H9=vLP&Fac#2mUEt2wLqK z`o;Z&iwXm2&5F*Ir_6b<*J|8vb-{d(OdL^!Z2WIzi76_dRk1#*NeIzluXd$3%r?LT z;*ds}=Z@#i41jm@-n`oi5mMFuZ_QUiYQt{} z(uUJap#8(P9kvJpceLOFI$Y?Atw1(+1a{O?Xr#uowh%MS%lqe9YSwwJe~YhAr~lhC zG#HmUn)5yrTa~kAYMi;cN1<3y%kz(I(TbwBCt zuN}~9p9$pU3N}uW6{e|CD8?0I*(j@-nw)x*Yqtx?J4#Wo86|jt5ZVH9AIP@iu z=ocla5ZBcc4H68=c0XQ>Rje<8@Db0{>x5B9=Ey456hmT8{xc1Kl{i&g2Y%6_+VFBnsZQHVW%gsmoZF;>wkcU` z+&@dy;yUxvw;KF3h8$nZ;1+qh#oPX2`sFh%sPacSZR#KSOqI~F+Wmf{&ruh&r7vow zbKa1fPXyYXYk`tVk^21#+B@m-n$KbnV!a;evC!` z4TpEm0Z}%UdiPPzxItZ^*f}J3YTr~U^&n2~GIZ~$#hEGa$;)WVcn(+Gcw4JfpjpmA zrayhWMtVsFTzo&}+s6Sp1GTqn_7MeCRBVb>m>L=;E(jLGEb(u+s6KW=<&F7&9%uUs z{5cv&tNOcn;cML7A}iBr{?hl$1mo-KCT(q_Ca)SAh5RCxfg=}>sl96?f!aV8HyASqqTyxr;+%mUD0o`i!Vn z$2aTN%dz{#D^V&ySce_=kRH-=TVP7#J~RMDXsg9^Paa^(g@m4Rw0r9#Z@f=6bp}PP z#@&@V349-&zZacjzMMBbX9a(PigOnOvG<0miNIxo0?TE}BlqyGFma1fppiwX^#^xp z?d@!sNux|@9c(3BSa{H%0*(8`RfIt(trX3D)Sm<04~v!qylRNJPhtT){zs`2P& z193umzb>Xv)g0Z7(>_#~!aPgn8N{xWW-kw+btLoH=tRSG$26zDjHKVU{HF7%|JJV80yib&8qMJbMw`B%4@cM^%m~f|epLiu3RTpm*xqRYa&9uLW~l z?mP!!tyhTg7gbzcmJGTipPkDnB*KerfoXpN6g9nmP4#wGq%1A*?|5Bo$X zO-H^T1T8*1j;Or&m6;;n0KC&L!ouCs^aWVwkt_B42_+mZaC~JneGPu$^+OFZH;9}o z=*=lC7MRLKlVNF5Hj^1t(%ARD4DS$b)g$S(@D({vCL(9b@vav6;$6grEgb5XDso~i zk*3>?yY;nLa*10;#G||on8oY4ud}@PYo)03QSum6w9C+-*FrVY_%r49JLTd#%`e5k z^Jvu;ti}2c7;J?iYvoBu&B%ftOor@at7kFkiYB=?Mh{vpk`yZtwJK$`ti8IJpLo%x z*_z1;uW1?=gO+o2atBUA(wVFM9N8o}#{2M4 zct;_&C6SskA=rGVDW@Gpmmss`-E(JHYhi#;$V%d-R zxOUKjiUmH*EkbuQ_L+$^;u-&i@+{Z zzlaN#-+!6R{AtQf`o;N3!IS)amLdGuaC%)CV>RzD=n%;3MK>ziHSVmTaZKn zhs{@G7AR350kLr`wX>}S0`=ihnwwTUYH|~k<0hNebMAqc{&g?dhJkqCgN`C+r10Qt7|O+ z#?53m)~{j%2vgfRs%iJ&RtQ-}3HJUVB1}bE>Y{%8+vuFhcnZwf92_$1hRhpic}cot z!@EG?^SeOPIKDZi_(yDq@~8u#~Q5R65GEi;&4eYt8lvJ()Zk`2HS@FCcPUmaU{7 zAOsjh?Aq&~j)DQ((J4*_5&;^l(pr?o2uYu*z6+pXR(`$aD&RPwOWx;b@dz+!=b>9P z(1ZODWl6SxFQ9#^q0hqVa8IR?#jVFSgLNZftl=fcc{aJKO>4{No=bIsgh&!(bvOSQ5j+Hg&Yz@WQtv$QtEi;jcXccIVNEH zcnNlixHM)C^uGvrSZnVe=XP6KJqa|pAOxI+Q6So#g_$7Kzs*6uhf-z{-5`JniH)HJIO-{!A4k07JMgg$aPPIJxKv$Tj$U~q59f~I$`WTRw`I&?&zG9N3Rm!mw`PLoe z@uii^xv?c3+9e!H8srsf=eern*@6FV!6fuCk5jiwPTc$ho=qrBKA&zF32k9I1_`}- zbQ2yWN#R_VqgU8+`P`US(DFSIn6wJ02h>A@7pT_reshYTTrr}q^%na30;754$yS{} zqAaHuUB!YjhnyTyF-I5l))ep$P~-OrkCP>D8IMe*ZwMQkd~Pp)JEB|n{vlimF5?=& z5as`l?)wkY!~gI{K63ywxCC~%bp~~$oe@cptPu=!R|x!2=)@!?kAbk8xu~8C(ecYGpi9%=6X&VE=c#<2=dUl5@tyC+ zcFOr#f!|~6SwcxbYOQ|Rd=My}8TDrdTh^f5lTU{y_<;BQs`fx0fZoswFkqaSZif(z zcPF424!PiU-sO2zAy25Kxf5?f1DlMEJC&DC)m3 z5OhTpEm49)dc<*k>pnBUlVSPYBdCgUrW#A`P0a5@^$rrE<8n$*f3fOXk}%qD1<*o= zMU%RluTq}=F^>IiyLo;ndf-`kFd1&{>@w@+3a7;-axYw|XR9?yosII~Kx>mIE}2_p zW;$EHB~*)z=>+pqoyQBY2sCZ}o!y@|Y#_}~N!{$w*?)2oDUD`a45Lc_w0O1b_viAW zAPe9}$KYkh@U&{b<&|;fgf!diLwHw#CAT>)h7S>%yX=KF_Y?LMV%MXfHtXX`(i1aD z10l@v%Ke5=t`!>ErkNd)sKE~J3%{{rkW!l~72jq-9nG$|)Uj++Hfh5qOieSxT?U0n z>AvpVFh%iR_rn2~8Qt%`JjbBOUm?wQabh3JMUTu&>w?Wesqt`yHLVndn!Nkdgt_=N zRWA1lTMn|{&6FfubqyT zdi}!}dA20OjY@6mddq-+aozcaX}hWrvPq0t&?*Hk}eO0?v0P~}uj+W7oRc%rQC zg=%-doKe+|KBGwop(U$K3mXs6xzE@F-?>3(q_JRk7&YBzbJ`h4Y^~lTtF}5Y6&c3o zFCg2T;Ld`{%Ovelu`i*LI@9c?c-BJ9vhV7rKW(x@%t<~4us~AI@KYL12ffnYwkgJn zCE=>fe*XF*84q{~jP2?YTg@q6GyD>B1+QbF%T(#J{NSnG`J4N5`nF$f;JR#RiA)h{ z`=u+&wC5nY3f~#Jd5bvH%Z%9V%MbB6Z#B&J)z*5VXo@sB4fgf&!$H$9S_28W;bDmQ z+0UExgH6Kw=uy^q$<||n-5fbuM}cGzlxmP>DhmAA-&1~4RK$*>9nUmHx%==%Ks?q2 zApuO|?V?Tv{KB4qZ+|f#{ZoGZG=P<;1LF-b!E+JT|I1G9UlK|DiXx^6D(KAwWt@?2 zle8)n&PACR6sB(lu*xfe9}X8ETE9bP7~{RQEAovLOwyt>1Ro70TxIJ77MC0I9#yxh ze%8=Z`gKS2u@l1U>p10rvPwyVvX}w0z!Z@is;w_x+YyTVA@r}cA<5U$oSKelH6YHa z(#)(;lK?}NDCV!T{ z_M{vuBG7$z>$wmXp-`A`gtuCZS`!+IcOrQl;XWkHv`-n*tzz=iQt-`{vQd#;Ro1v; z7x_Oisx&cp=^H-L1LDVgf+@PsDRvKa(se zSEn2NdO|<+RKYZT^_J$m6OwU;4QHZz3kr0Ma1CtD`T4$noGErvKQec?*$_y@{bgY& zpiNYhS;tGkIL*$KK#L_%$Bj9}o8IVK>6e3G1LIT~iyJmxAC30aZ1S;$6_xfkxg1v&5jmqX4$ITV6<5s*HhvkL7ZgipKvhnVe%nCif z`$Rox$pq1}rwcr=*vLxWxT%>uyP52qe1rKOsSEQSC~q9P0|4PpT!b|^9rsl8uIvdM z;exg(_ULMRm{Zc3qKKouVX_kBZvqivXE%oG$Y>ZlhdV zc9Xf}#|*=O>6=O(K>5*~YFvlrmrz*-X0dv&>nZZ9yEey>+G)bu>O(fOJi9b|wZBpd)ySL`4&K&^ncW^j>r2P28ba_VT~Sm(e9RG^x>%BW$%uRN z@zXM#*qzh>r2(xb)pITdBfOpUrxH2@DNZkMu2eAt;@MjN)0zZlaaeB{V zgfNp_ZUyOUAAT77C3Y{~QwBTQ`-6F2z6o@DjlVih7fg$H7vYs*Z#Q1%o=!ZV`B)s_ zI#rXmD$0L-Do<5@V^Re>n^T4g`9I)K2MZ9; zp>uqX98{q!iDtIpz*(6{Ym+f@k#VCS&N&xrM%2;V#AzRkEv4@pq@99=-rS_o-G!;1 zP?xBBb*wA4(q;MlQyQ;?r5{a3mZ0{|81Gb|#1)QELkS@>UwB~Lj>L&=^ns`E@!mLK z+;|{LT(PqI-<2X#czMtubGzqRdSbY8;7-oph6#^`30LZ0Vyxf(BF*9)8z2YNm>DUK@O5lw3s{J1747haue{vhTG4+1GivU^;5*Cky-S6Xii z7G6<^tJ}O6r^%J?KNHCdAO1VGF;o{c1r4r7FTm3Me?Q3i%gggGJJZ5{yJ3@p=U$=I z+b>_!h`+C^yr=GKjnE9k0r*s)i z|HiH{eO5fHg%^L)0%%0A?sLqAT07X9#9Qfdj4!+O_-8ar_& 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 v3Y#49LZTlE!>AA^#zR_%AZWsE%)iKR^HN z{pZ{NM`OQr@U| zBSS4UsdVEAqX;oVAu~OpM8CuYR^~uCIUzCoC^@|QnK>HRIQ<70{(piQ*czGJIsOCsuUh@hK!1BWf7AVcv~sjJ`VR=qe}i!L zus8WfIsbYR!GFXV+1Z*}{G*Zn3P=4HaA!L!6WjkF>c7IcI9pi%Co!@A#W{b+7+Tmf zG5&|si2fI(k)wybv)%s(12+R}YZK@Hz<}(3k>I}>SebbI2PR1Wf{ELIdSW>L8enbV zbmx_SjJ4b zxN5f5aoc|O**?zkdh*Q)wy_ok6m9{D;>hV)&b3QKhzq5DJ76cGLNQjag0a}x`VoX>|jaVT)C7+LP zEFilaIRTY%3PEOBEm@JB5975UmtC6!2|I3TH4ym?f(^wsoE_&lFQc(ojbE-nL^wcR ziB#K)F2X`XGgnn^x`zJ*zHA=M(WWbka|XK5UO6qJel!tQteGxk2-MbRmT&ba*av2f zJWIY$X^mK$oJZ^|#^MsFU3;V$gMq=^h%rC2i0hPTc#Ng%ER~g>Sc}7@@p*|jgRPqtedG>c0H_ie z4}9tMPIUQzW|2A*ut}(C(r6ItFSCW4WBiH$FHMnB1xq!R1V@$G?fpCk_$Tv(fIAHN!HrV*0_ki|HKB+OU%7(1H#F4$uU_#|m| z@Qk&w(YDDUT=N(r@TD<$#YKhx2&x%jS@cvy3hMY<1g@rA)q&Pnc1FcYhkpJTbnh+b&#GtvSp&(HQK=8CO#TgK52za^?uAmN} zyjaSnC#k;$U|ifl6ogPn_(H;G5^Oxc=$xX2$YNWfL`u&bzUQOsXca(MwtY&PlW`$~ z)TgkVDab-F&tQ(|UX}ERD~8-K6FG+~W!XG&%Mw#;(K9hOv|Ct<(vXh(Q@)wE_f0@< z$kX}{8KeAKGVRhFory?U`{+u1p<*dDnyRPcF?ZZ-IrNBfON#tOgr_K1f-&JW`BluY zhhHIC*?A?&Em(BOw}cpULsB5t>O+JyPmuGR)uljX@r)LY7C1$EdkegejrMDm=5x zh5|#sy-l;v<4$)Ot-NMn1OI3XT;6@LRTF+1!kUyVVZKC;#Q|h#v>-IvVtDEeVq*7} zNs(n~8tF#AaSxvdcKHEVd?B6G_RA)8upq?$#8MVbjZx8|w{a+3rW8GLjiqSC)p9JK zm|jk@b`&XNdT&O0l)!lT43)CTe&fE7Aop<$g2Un{l(UE|T&jOAY<|YAU`zR6XIC*a zhOxw}DXFNgS4_V*0N9~}eJvZnYJ`8E#(B}KvBma$pmCjEIyC3j`bY+sPA)2GsZMd{ zoKp`j+0{3EeoS}Lm0JCsdlwXAL)maQ=}P)h8UcmI&hI;~;}f8LSe2CK()@MnlMn)= zkE)>U-Dkot{QcM$B-s0oU$ztJ$4%lkp|Wq$-|PFg1d3)23(WtiQiF-xXV^$ z80NWiWIcq9IYfL*wdVUPN0VJLq;j6*x1&yCM4O1=&_hfgi7mt}o5Q->=xo*4+h>7X zr>zOU1ezMk!@^$BE+dmg%GB!nRzxXi3Iah<7`$$a?N}Z$ND_=ZHXsDK~A%{V<`^lNv_yke&F^55|7g3 zz@O$!s!e>)irxCyS!ogG%eHSt{#u$&uPr6$M=4LVxK+ei9V_q_~C}q zC0KHh*`tUct_bEV$E8&rtg&9?E>Ez&85_SfnBE|84~$|D^pC(}@O1`HC03XeE=GWQ zC*7P$TqDvVHQ^u^$If;_^^MLw@9(#+Ffl**<;pn@$ldCDW9H;hjh_)Y!|pX4SYo(6 z`U+O(o==Ulv$Dos30&RDTdfC%na*sV?(4pe^peCZBEss!b*74vk6j|~cW&gxP^(Yn zWmO9SYDZ7+-WxY!VzpQu7Aggcoo3Ydf5@hO5MJVU)nb;{Q7Q6BBge$u78pORe21T* zIVqb-glbfcqs-(H3{~4eHduT7kk^%!M>Wb+ky51_E~iyPSZs}exXVmMvoE9Cy+iLh zU>$KG9`#B<$i?mQz$HR+qS-s1mZd%293CY+*Wrw4M-SDGN*@o4ZQ>3phsoxSZ5X6C z0;OkZMc}VVrk&tzt2g^eJ)jivIE{J&uI&@vY1aPs+-h(Mu~`d1vZTnRQDJ7^^~CBs z+JkFd)fv~jA-@ik-TIE04Sbe>mSo@tMmM>>)|X+MU@fcUkXbS$Ip${jadh&SKwtrtP@(Zk2OFZW_J{@Db~H}T~^G$jbwzd-ATNG=;sNZ zyp;tyUy8ZC=Sm52uE4ts;+^peS&Sy|oylFsVd3g2EZzUw{jA#;(2jhmyF{6fxQ^xe zYYL5^y5xn!H<&LFcG_|89*y!$w7e4FOSH{znD5q(`3vr!>$qvv&65YvKfUOm zYLoJRspF(fJe;Ke6s~`-=dx5^)sWPXzp^2vA&?*x_!rvpNy1qqn`i}S3e~FwZ0ho6 zCdC+uf%~O7nR@4Zwx4y{KUegu(8}Cpzx}hnWSX8Qjfr5GOOA~_uDiUty|z2IeXc(r zr|)tAWcP;gS$oKO=?XxrV0JaSdXO-e@53YK8zh%Z&2bc67I_DEu)<79?4|2C0yEVvq>3zLCKG@|Hi2gwOB7T> zy&nu4f_O2sYLgA#-_DS$ZKBqT%a1Ww5j<%us+lqJ4z@^)xLoNQZwwWPGIUTx%*>cb zc&sWyve6Z$lR`&bFZygDy^J4>=!DEga3Rcf8SbI_2l(6SBuATwt==N4o8hmnQyBco zQG9+{kp!35d5A1f2+bp-;RA)VM18h|HkNrx#*eXc?qr>Yc#`oj#WOlr2zwRsBeIk4 z#zhHiNMStPP2*3ZACXU^h9Lr<_dzb<8my?#W3b9}kpn^Q(Z@iY;TfG^-E5gN6OsD} ziXsZZ;M@z>B{Aq7kp6~E%rgsC5y?g#DKX9*`h@Wvr@vJBQC>b9mHQGFg^Y`DS+>-Y zzKk+&(Lzz@EIJfuNKvYZRBU-~A%n2zM0gX5{!|_RfZ176oSz24;;AX`7-bO3hH@U} zj*v>sO}&p0#fF^QeBWHjA>Ty&tSR1YOa5We8hZmgIQRn09HqUv_qri~&daffV>edEl!kXgrPa)9hmT-N58 z$IMstD^=tbozQ}4yb0z~X<}TkTSva^_=#m%SQtKgyh`W$O+6nY#8uZ%{OZe&$dR5* zwteJmAv}BfFoY$VV9k2kER$&BNY!XwSxbhxQheO7E+HK$8&yVix6sXs&4i{eyY3%7YBdQfGc+|1C-BjN-QZPK}UMR=-q2$vNY8kYLT;$yYUT;SVQg8GHb6Z|)nOViB_m>i)Mac$`S%}%` zOunvdPEF3I4xYp6h|G~j^)d6{nH<)TcG<57cJ5_*WS;kLRGrlGby2mN;+Ep*ie|zW zAK8*frXq)NMQX_Hxz&}0Ct`28*se#F(*dXC)8qwNH;NN11Uqd{aGu?X?80H9PK5IN zk`s=JfrfP79MVyUP1mTe{yLJ{6&vwHDf4%nUaXiWl($QKSbPA!H3&8cS*F#dUgr9T zX^`zPcQtXj6T9$j;TKZRA;WHh7QU`1n;x2r2cvuh4&fD?lY$n|JK5#7C~8rr5hPdt zC20B41Orqj6FVbjwDzl*#8j=7VR$W3X?MSAoXB?m4~qg%0^Czpae0)+Vfe?8@-?PX;!&135zL-ormGr1<%2&{*4eo+DlSYQ zpNsapcV1*NqrSBtFHCK?I-6YenGP$CIun{`%acIcr`o9~R66N`0{6Hb8b-Vazzz7^ zv2+p{%CUSxYly^2u)DxUzmYz85u@AkXCurZ&8!qeO0V#J8xg3Q zXPsnua!PLB%{z&ZiJfP`yZm!8ZX2Fs#6v@oRm!?4P29*EvJG>7w}8zlB0&dq%G*TD z%g*#HnPh^0^#q$}qr$j51AlT4-B87B+q>(nzv7M=@QKu?me+=Acb^=*l5|LaGt9k2 z8Q1Kvbeu+Q^>H5C}HY2wG7(hZ0~|Ud_w+B08j-603iKe za)*qGv%%l6I*GZ!$VfdI;SY0Nx~b(>6oMpBocyQ<)9j9QTu7U-$QD{>Lj8xdG*Hbi%MMAvRfX z`=j#`+9y#|yb(%SkuUTzkIHFoefA+k#_7h4K2%+bUVaAOv)wVkk$RA`{5`dVkwzTK zgl77{S`b3aHUx2l$J&_L#)SOPHhAX*oGpVhxVO-_NFL~Z;-Z8sFpp-6688alYwJ7) z5TSk8pLiz@c5bWUFk4bSr0AMHWdrZ0>l8H`;3*8xIp`8t@(r&mkCgfd_qk0)xj%4Ia+MTg8?ionG#lA~Bma~a z1yvZTHAgL7`=ZOAB+H^r^;<5as@ldjl~Y-7Be%`pK>uueO>KAs97_0%(JNA6L`9;K!t|(j7G>^}K4+LdCInMx zo1*i?Wy^(ECJd@bmpDxJxlGV&vpt?Ea!Ixs)FD0(?vn{CwZvFLgq(U;DVILETv*Dr zg<64qhXiN#%3(vq4|3ZU*XbL~;)C~bX*OTTOz)TQ3W-+WyG3ZatoI?NU{q(_7%8Y$ z_dmuevYk#YZ!98zG3#Meb9N|(@1_i;!Z^in)_p3ejRRY>2Y9*ac=+Cr(5C$~IKp93 z$`126m73RCR!OGVv^BCoZg0^oiG-p{V9UQZQpc5F=$DQC7ognIsqjtmMP)M#` zIn7)M{%tmuXi#2`y|s3n&3tdqP?nKEPOZk*53S7ZME;;^-(g$|Me{N%$f!qg!K98{ zzxrF6QLi+)^ksE%t4wcnxG@p_Lk?avnnZ9%aoQfxkol4zeSwLALP#xcA_=d{*iB{F zX&{ApkIt|Bx@%X^l#-&z=koRmOMn>D7pw+d)op~eb0k=Ec^~WIO3;~Wg18ONRFHL3 zpHHT+HcJF_yGVhB*1NxUVVQdK`Aj`%4%o=nL5wQa`8%`b2PjySuG8;X#4kmavVB>u zq2gnbtE^@bY4*2qX%f_)H5|L(OiuJ+x5HA?Triwza3&(9UbJK+h-qeib`a( zYTBB9Rt)m>L?lA{negJ{#O!ycL5G4rbgXp#)W|muU-%&) z7TIldmkL3=sFTT&$c;(j7rjXTijmAXs5qE`N55L4{{`yLF_v~sDD8G!2H)EO+G*q- zU`I$uO_=cI;y+?Y9bcjjov7A#5GC=2qy~1MI(=Z4|KajBdQMdF9r*X)#GET9B z#S}ceQeoQMXA!Fj?WMF1OEM#Y6 zZ((g>EMe>9?C4_TY++~n_r&3&C}TIz5ATyv_-Zec!76V~9^4F=fV^A2r@AwPFI?Ct z0(96{gynU}&c0>t7P!ObAOJ+*FaozDMqr92g|9rgG_E?z4XRnpy`PAmBne_BXoVZ8Dkp0uL7DGc9GxCY8jm5g8ilmUX}E$z zEya5)FH!|GJxu8x@)qQ`19-c)W5|qGDpHudT&JvQB9r)47|-GO%So{3?_YwL~?mu|>e>&#K|LUF*4{;7IY^4~co zf{%*TO}UcMRGxi2=|;)bvT3SFzYXx-#HQFByOZB-&d*)E8ptVU+9Po4-N-%n413OT zeSyz?#SSC)FF0+E>aP?G2cEwX?2h(CHry(~-A}x+bkx#YKMA0^0sq-!GHEqmV1NJsEdF>5{r~1M|Lr;A zCI-ePj{oB;epW~Ve|%;9T6c}uro5?1Gdf*+5b3)LN}{qju6S;U{|0V#gXT1NTxW9~ z>8=WyIv@=R0pT6_fjn~^SYjUcVNQ!oN4O7b zHk4TWoD<#6f)rT6EcRK-l8klkggo@#YU>NSmtqUr7V!>c3ZbFC&18A{%0gvU(BLNh z&2c)(M#_GWLoVTDdD_ZS<))wdb%1&Ju>2YBZ(W=mzZ0D2ZJ0LY-5|p(`Y>d;g}C=R zdUHdtegUJ$ZPrkjQ`r-!kmzi*FkfygXpSAD9KuE26MMgrqLNP$`l{oR8~38CyPH_^ zs1iY)kSi_PS7~wr2?Lqn%T`1hiq}kItjTAakUbG}DY1?xX9}mhJK<}8f^D?;vyk|) zyx!X1<-CX4AV1@9a>U|w1uV)4Hi{&UEd(((24Focs1AzkBdMzp-&VDEnui=U^jd=w z^CRn|Tw^;L2Ebh_`>p8Du^dwzq7ztAY?`}>DSnTt#*=CZ{ybPxAb6#GqA*l+K zgkqnOsVl^_hkHJiUp|$06deB=iG?|*k_=Qx&t*h6foKNH`Cb|&9a!^ggk3;d0_K*! zK}Zi0**md=F5~-W&tff=QQZDB>K6Y`gRB4csK5JCvO1(U@*>7}_oj@gn`<0^tuX>K z;D9v{m_Q&YHYq_*3b8O^IAF50Ybbr~Dr|d0l71E1WAT!uN~MaFRUN8Ul`)5*g4e2M z)3brr`r3PalUtGbM;BY-1*tXA=Vv{WUDtExb(gNL_wk4VfE0*w%Z}>Kth~SA&wQFU z*G|Ub;dZKJXB!5>6#iX9CReBe?DS@gvVS_LdD{TE|Rv-^EkH{hz*>Wyn8Cp(7PZHCKT4u z*pNn-Mu@0Sm})Re(uYP?O)OM@nZdJhWSQ4vH4@;sNCG(%6tGfP(6SuB-Hdl`p{Rzp_>I`xeFr_|C z<_xP778kpR==}zNxj}El0Rx-CAJ8VD_vFD2hf5Y&W-xAF4od=tMO~Z+t_&E#ns!@i zRA%Ak&f12UNj)oQ0NM$3KkTCElV7qNg)y56R7m(Unb)(BSzSEw-7|FTCsAbS z{^hgf%1>U&vMNzLn_mb-D$_vFEv(`}6)YXG2n*CeXz9;ZEvU<@Cbq4%r^d_maXx!s zuxw*U3IXfBrZ?cs8w2`qff^lJ%o}48`$UMW=>hAYQ<&R?l&<@MP*)2#1RE^MC;O)P z_0`jiXLA{>4sl+O=qB~H3be8~t~=tyce^$%TKzng!P}BIG1e#(JG!vXyS@=Ww;Bh7 zJ%l#ZnI&)iLt-7#JtvhbR&m%8c*hoFE!@MZaKlQxmN<)o++3)#jDb`35Mc3+jmpz3 z<Gw9Wjr}ys*xGJ{NGKQvsov5Jigz-#VD^I1!kk%Fqd>?K)k}I$W99Br0bhyS4QdK2s;?4%9WIp*?0%~nf!v&-VpP{>iT%>tD0 zFDP#w7F4NNt@8)%GEGX3OCCU1&B=jc&dI%z12@`$9T4-OJXLljhXdf)a*rBqgBB9;Z8lEZip_xlI$3}ZAVxau{M`AySfS^GtpgDP;MK_mQd zHpYlI&rrhC0Hw$cZ7KT}TD~Tu{a61{Y4fIsktNbjHOT_|>pLasN_1L7BUnQr73#(q zu6U&w&~n)p@XUN(B&WV!*Sd@j8Mc5#6oQ{mv%td?b=TTI3-O|x z9A(r1UyCyez2~!HZn{X8w~O%}u{Ehc3Nom9x`p&o`(&tgChh{^4}s-5fAlTGC8vlq zW^Tk%$VmWg7abeBpLpQ%P=ybABOZEt$Kt2U0BsM$ozUC}eT)#`5s6YiZQKFNQ!%m= z1!8ny^IL%XOgXm0?QOt}L9!O@(N8($b$*O0e9+=A(iLW_20LmKzoM)&{wNQkJ%X10QPpRl89WyyeO}TsReac*l8cGZ5;UOw0z?X< zuP}TN373DQk@8M|a`x>HT$MNjNPUeTSbZYa!W~#V1Qp(3{6^5o++M*QV^aZrv7dyp z7~I>}uTEDB9(!A^w8J4?r5XUWDveux2i7s|Ug2{^$&w4!;l)690$qBDf=HB$E4m;e zCdsst*}K%f=2~XBy;A`!UW>h6zL*=x8R_;O4}%DsP>i=8Xc>pym8je3GpPXCvGsa3 zT&*u4--Ls71F{HXdsTUNfn^PiDqaTB-d1bA)KQQ%A1TS|1_mAL3dWtKBFWDY#8uu2 za}Zq9x1?yIsVEhwrZ_%l={JM+Al1v4*(dKa$bE83{1eakq#q7O=vne) z%LjrJD={-#>~N^y9qby~6Cs zV6}@K5hXIZU{RzNgEWF*?626MmS0!0mn)<&g~D*u4lJ;fY=-SEp%JfvD-^iHEPIgJ zR53fAx7@bybOx#JC~V=&4opR(G_-uSE-3q~Y819^lY=#3Nc-x zhY}-c}?l|2+IVW@p?Y>jYWO#Ir9=B8) zLn*BwzA_Km>a;QYY{Jvg$$K;(Df+mLVQjZteN^y+`Pkhhn}P_4W^p{aq`3DY2w!1* zy;QWM6(4D;ydAp-U6Z?X1HHw!YUMC?b6b})q@ZA<1Q9^p0g{|AY;P)*#x5`k>0d}Y zP{m_(JLrOeC;YqO$h>MUdmO%(DSpDQ?B8&C59mO{JDf3tAY36Vg*)4$RUS}U-zR;p zY~g;>=)uwFd}z%qzhu3n$DPNVMkqd_QM7+i(7iFSU)-)VwFW@Df=$bJ`no#Xbj5yn z@x`wPt||jHSPT8oqGPG{Q>;O^6#CBBgWLP@{&^r&T;J2_9HK+`ymt|S!O>)G3#PXg z7=ZEa)>@X`$?A{BN$U5B-*tOoPZ~dc`U<~z9I6l?MxVH3;%s89F$Ost%)v*b%UzFNvifuWF~+~FVOnd+z2T` zHh9g2ctqybz6JWv_i%#vIR-NikEi$Uo>x)F3R3`?XSrr^QZ%~EVy*ZU9&dpkRd7^lPEed8IRZs9h&$$7Uv(*q zz8%WrgzroUDw!Ye4fw7=@Va^^lyI!C)9h-?>1udle?F%hV5`88@Mq!Aq+n*opgno% zpi4+UeZNcCA|ymcwCd{+Jcv=v&I}<`4&dToSoI(`Nw|ykc`Yva2?U{a1IuG12Nt$B_x@zWZoYR42H$#WTQ%mA>c;}h=Ka5+@>lG_%tm5NL zM7>y1YEq9GyUXfa56IZg$hyUO!mono*BK%BD)5=@`B(I4;8`) z{N3VB>hF5kizweeE*Qrdtq`U2(P0upCH-AkYA9#T`3;wP62JtB%Z3cx{C}F5GI2@u ztchaf*w{obEr}^cupv*IOa~TqjpUL?XRxWUp|&~V9PDmX4|AyJj=Aqao9ODepY;i~@YYEq@diJL$y{o_FcZ`g z(6;&led(QVvccpQ9v>jN%*?pQHH=^|@EcJ`FxNFXfS$}JX~|MO^ig}EvBZ9-qE#N^ zG8%IW+)(w9qp#&bO`ud4Q!m&QHp4!PzNuRuf-UHqxmm1ZqjDE)L);B4`a{1$TY@tl zIYf)OagVgCaMwR|@R1}_zD}jL$Z^dPQ3Q_@8keCY$|6d5Hsp?y*da3F5_4@fZzsSa zYQ2hE3g6J9*vdVIst3tdQuMam^Mr1Ql;AW}5Spkc9YKIHfMU077sGtByUK_2XHs}(X0 z?j6QB2pFhq`z*j^^wv@5Dg~wnl0=6|Z(U_KO(D@ZR1A8aG{nBXA#yPK(!M$RAOp}Q zC+I?}8TEF9eb)Lxcd)|(L3q*@+@Do_vvEjK)s$H=o8Z#(QW&QfszUs_CWp@)PhHNv zI4mmgooyUA`QuF7PNH79OUX*0DQuI{T@q{`Eg$t~Z1ozOr`OA!0!pbN1uL{oL)1m5ZbQO)g8t(moUrYlUQPl5ShUXc;) zC6x@2iCH4CD&E4qB=eG7(9LGi6HzC+tkbN^F4{bk+K(e8+4p}&#ncgA_TA)j;K{dtxA*QA1rBA$ka1`Q%G4_H{qeYhv=@5t< zIlF(QTR0|$;nCMA3gwE@)~BUp4aMn|bxqqaJo=4&b?=r4wWPI$OjA?y=OSsbBe!~0 z2s^Vu2l_5t6(^;d>iuiMfrywg>wLz$+g)YZcgt0d2+BxvPB$NS5UAeHJ~b;VX@dxu zHBsB6(*h5R#E1!q9aU?rVCy%UJ|ko45ohC8?C}s(&a6&0sxe^h=MOqeSeiwA9AI zP)qL&o`Y{7xz)nGKu5M$CPRxR-VY7As2bUIwLeg%Xn0I(Vuq&q(tg>vp6ShMeSS(j zKWDw_G$z^@Nr?Kr!-$MA#OxuyAxI%fcB2nXCn_-GJgb;INl-UMZy($2bF`Lad$G(3$TJm9N*9fm8B<-TGa$E+oeN(J#) z9@#`s(AzFN+P*qmHCv?39i50=bFNwDH;dH`cD&lH8SARsVR=ONox8oS0;{MVI#tVM zk^>us5Nynjll)E8$CHP0>I{R2r$Cf>iA`ywz7W zJ`+kq%ITaqTWyuO=w-CCX%N|yE+ptj$V%$nA;&g_VXpEie^tlEvrOBCNoOO8ouR7C z(t*^Q!=7kbOf;|C{16kv!M7Ntut(Ocp5$TTFvHE#MjsBM7QyPGcc_;L5Vfc-N`vE1 z3^5M1AqG3KULZ(b6yAPVx&qfV^WaSDBrp~|e0yC4wp@M>n_O&!F{BpHW?#b)-@?*v zNImEWyTV3$U8J`I&wh|<9?tQhHVgnu5r9FFXOGr5*g0QFyXqX9({v~Id+}U7_-^r= z*8IF%&>$f(tZm^7ilFgW)~=uGq4aCSuu^C~Qx&7lFDycXrqqR0Qs{Hc;8YP;)ji9% zu(S<9<9PepX~w+5b3~awWe_LKSi^NDtm$mY`UQ%a4iq9LhcuYT6z&JeYo2mDM=>FZ zJG-TD@2;O&rQdhLU`t&?1sfAC#Ve@hdVcdHXGwgQITgAUN2pD%%d& zK8E(#M<8!Xw~)p;$W67~zd8MYg69c|_9sS;;6+5O1cw#(UJ1+7g&Yhn18?Ui*1S9` z;27+#xn#(QI_|NJgEynSZUJ(7bl4}-0zZ(a<6u0gn9x>4Pl+o|P)YY)6Bd8ch$BSE zZvAr8N3-kvotJ?&tW&GOZ4|Xn%L}J?O+OrK7z<*pe`pjw4 zv_{8>Mg)4S5u020I*A!q_^!Yd>}ZJ|92N$M`*G~fk9srsV;D^Rdgk}pD1qi5k**=7 zRtioz3phvH$YNEMr39l2AU+9cj$Myw2q-LL7mrkyN!nfb7#PXeuP81weP*=@H*JVF z5PiN*d|3A*h2QH&H$$PFh<1Biz9hSNl|%{>Rgv@_K9}?Aeo$~vjzll!l(?QWb6UDy zE$_s*wEb7?Yz6&5bHk7pmyq5^>StT^5-G9Nu_eMDBU4^12rGC8kCLs+*n7u511G*u z5#TGWc!dK()~=!G{r!lskIn`NT*Gc@k%vj8eb4A-VSZRQs9bF$3rmK@%~K=Fv(!G5 zN{CHM7#vtauNXl|2q^F0B0ZnR@4N-yfWGL=c`nL`J*pAX1`9b^n_;*avtg9CM0fa@ zbL)y{!!M9ID&EgZU)_mA(>G45XUMt^egs@K0ebh}sV@cAxh9#h3@VhjWFMe@LX&=f z89)hM*uO;l>4Sp*450}AUHz-%;pA%Y-xH_ccp0gFe)y1W8>_^j(k9I&U#|)%Fi<&_ zyd}xr+ywDFveluY;vwM#<&$YdI8abOe?G}f84(`j&Hjmt_WRq~`>)$OupM|TOhs|3 zkrQ;G6oT!;*o~W(Z3fyko!tSLRp4c}eWDO&kA^aS6Lr|WnA_TCePKY8yXsw#JbGF$ zn`xIRVZGp?TASwrFE2Q;PY})gLcE`Fy)N0VF zCjm1mtFQ1dsx=BktLYMBM+cD(SPFSN`T3M4GoGc4{_4p%YaIg1kFoH9_)U3w@qa%W}R!mKiGuVLTTh`mQ& zv=;=J4=whrq!x=6!+DOzn@5mbDpsl=N<`HwEKCK>WXpUVRBh@ki!8FG-m&hno z<&cIPOb;p*SY?Ds2fhWwjkSt!nJ0t_4!1b4an4ng()OgajT1Ss`UjkcX$DDG zeuyMtaZh#9TSj+nB{^);PV-$KK9jZVDAZslG5o0u_WG^Ju#8rRV$H55tR6@Yz}o0$C=u2S;<+Eb9LZwT~YK4jR5wrH%w9 zJR9yX*T4B}dhoOEikMFIICmEd>7|0f+OOL47NAukscw1XPX?VMY8*Yy%}$kd8Z%jX zyJ^B%ER$U|>u!}=(NeLVmcZwkxpX8Kkt*)KXY`X$F%>UVQs1Lb2?vy@uA83+!s^P- zV;qVEL$Su}ij(v%q7TCrXO}#h%?_Z(0ku?CQ(P#co+ZgmjTYv1lawnxK?mD-39xxa z_>I~T5oY-S{gLoXkY_YvC7jUJ$je<0^vUSADn1_Z9YOZ0-~DPd$V&DnHjBE8?CecZD-BCw3ofGV_Ea@mu{6 zh{kGi0?mRMuOMg*yqRxgZHU=J!#ze~&csBl5#hp{&bL9EP6_ECMOTLGP4VJLKT^h_@~zjma4 zqo8i>S)$m|RY+G&IxtV)@-8qhd_sG%3@~SQPh%@vl`h-2(D%{>g`|0zw}?dv5>U^i z*7OP%i!h-mj=xe2P7~@PoLK7iki9=|TG(=Pa#WwRGx-`11MzMnM1iD5SP_9r9r534 zP4wBa+|A!C#$bxvFLO1D)8|vXV?BRkK%(B++Xx>X!IFIX%iRE~GQ7w_3nXMpq$G#) zv`8nEh_{N=TPt!!AMfCgmnelV2;h3g>qV#W{-XvMO(y@mh^wm9>p`FOOi`#|9TOmy*9DeO(klbs>KXViJA-rJ(Cl zwt(^n0RVV|1^}S>cLm)))B%Dn7S{iFov2FHMhQy=*_W1pItVnON?yuBhQa1u5wo&M zrFm|OK6#ZLTLy{7%Ege+>B{sM)OYZddEI4{uiJ-A%&{$MJu!0Feri_xarS-Y zJ@;{T=le2W%@+VY990OeF!94!Sbi))*LcotNAINNmw|_xl1@k$$L7MO7fif!F>ziF zfyL^g_r5C8wfe!R+kLr-)vHWK#t$`}O-7?Qc#Ix=V@M&!5QaYc&&FI4IX24lN&1uK zD44|Hc_6d*c>R_?=ex{1*wnPDwpwV~)>o3qOw${(hyEsx8bj~*2nm{Ac5)%wIj4tN zUwh8BwK`8}l|_JIIu&fEZXl4FZE|Vg%s6#M)qsheD`A9wMf$*S zZV{e@1m%zra@$}9MYjClVoYce>^v+lXDJ<}DnUbfIQB28S&cD!^LizbJX*AHgTE#u z*)5NH?(<7FeshFsWWDop}i7PgCS$JZQ=*OP3hLN@+{2bSPPxm51cOV51+* zWlvv!&_lkWI+&zS=PgzP$u?_IU#KWH#iL5Zzsru&a?goa$~yGy_qm$xL4w4ask1hy z#tczC9174W>XUJM1t*|zI33mr31=&u0nvr|eVg~IgQC|^bqMq>1~7AKp0X!!Ivt zuzqDVitx`_4Z@IyEJGKCUzK=(k-v=;PQ?~|w%Fxgd^4`K)s(Lg9{kw}HXf}7*KJB> zX|&lYk7Kc-X!pb}o)nZg0Wl1jlX~H2h&jM3P8%3>*(h7M z8H?h{yTWH_-l|#zQ}%LiPH9UTnCHM*LZFx-xfsh!abBHIkC?3F#?jn6wRe@_w+Udz zi{Uo)c|M-pTDtH{HNK(Ps6vhkp;DTTSz=mIw~@(BPr7Ybm9nujPB(P+LKGHsWG3Fr zB|_~-cVY@S5TDSiv%|B4IQtJ1bxsv+IQOBNszYhD(xGpmg)4Y9#XgUDJhg;_RQb8v z;Zl5HExho6y9u74S3T`>vilDN-cLjV_E5Z~?HrlFppofnPmMv`&yh*)C^$&IxRRsIH`)CLk2%T;(Pn0diQw82mXaS}KwK|Kyj@w9b5 z#kQ~b2iLlDw*?IDBP}pelI<+bk?bqDK4g@K{`Z{uB5@&|RlMaIIu4O>ITWV$SDm-OJv&vShmSLZ8 zgf6cE!dWY2=8naKg_WCclN#5HMX5BAW?yeqCCg*RZ!}SozDk%`)6E6z**@;8U0z!_ zbT|4a`09fnz`8dnEjIurtnuDZ$b{6*M{AHf;h5)&#T2I%MHB9s!)w)q)a4#!3w-~@C&H{A zCfoDSZTy|1yTwtiEfQ+{2E}rKi~y}MzMN4 zl46*cX1gXr(v=1h46>t*uk3J4Q^R=fX@!ja?rX_K%z9 zpRY$N&OpM?d;vfK&_YzbCB_z6N76i|4$f?@y!_Q@xPVr{jrq(w*dC8572Z>lWnZ($$=zD%0yuvQ~wm)3D$*9&O6z^`#PNSNHBp15B+;N2E5VVV3F-z(r=t43fjx z>X}J=UV4g#X&MzFRxZTU%t7PI`83p$J#m3hAEN1nncZmGU3+AVeLCbpk@YRMm=8)qNA~6C=g4JPsxY}bdmi#trItGhq6|=VwZLm__W+ZdW z%tY__>NiCKkZ4d^JwSck))Je%N;8ppX5!P)Im6@1RC0T;!XFif5!mfAcG`RC%7S!7 zqN|z8v4cNn^6q!R@pxKY^*pJ0n?wtaf^W3#D42e9ZY4f%OcXwlEp7p0XTJ6Ek?lI^me zxYlsRy3ggjc!fk$rOl!4m~Qm9V7Bv2FzYRa-2L$`M@1AP_<>sTaO@#oQ)HrvTz#W#tudfmcqRqo( zgC?vLQqZ!MIAF(94sK_7dYXv4I1F-K5G*QYZEAJcRWp_qv?p1x#4%YE9Ed2k{xH?gfQsX>9#R`-P-D{TLX^KyyYnoz98aNk87#WRla#CBAzDpo5j zxemJ1jH8`)7P_-g{&!`x(qwDMj3|bxKbLV#*1e`cen~TJ4}<6)kljp%9V7PAoEGNQ z>?+HIFG)BeuRKXs0BM|}DH z?W;YxNKRsmTW;{X`^+ein=wEQg^q8t@68_<%2y@|wD0@ZPS9Jx*wyC>{i5ZZUj*dR ze=cepH=Yf34ZxHe;Snl?y*D*xS@J}?7zYrbE z@&p(l900?DW59Vla=#An8FECvKhexu^xm`ut$$m6D~e%Z>_?<8*bK~k&@phbgv@P{*0{F>p zEQau0L2Z)bzb*$yBFtmG1 zOR5WK2-y2K(^px>J1#Tp-Mh&`ndFLGmi=xm`<>?Fzb@0N4rY;m-bbSfw|on2M#wRn z7eLBseBbaCt8SA$eP!%TD9t2rrsyqs@{ZQo61F4_dkx)?2SI zul%nukKE!ykUvQ0Z9TU$>ZbV2ufC6pE6&$5a=&*JfAgDi25iLXTr9{u#qH)Z+J5LG z=)ZaC?09!t727Q^SuHvdkqP9$kr*~ZkH5fxXC6Zt(hz5n*lG{}-G5*AG?(g(hzncV zGdqkbA1GvFgxY!on`AMEo^oT!k+%T1DnfGdR({uVx|)N(wT zK?2F{QT&~w&F8_@ntAvbHGDS&%LCX0_R8Ha)-@M=_3<=+Acyr<1IA<_WqNZ!E_U&r z6hOTIep@Jwvp+JnY&(WwX}$wKqQ*x$4qm=qXQe(HYLcQND-Q{swRAZ>W^w>${O!z5 z#uGc{srEO;ZKF_$(0KBok_xPsIKPiRf(+bT8Kgkwb&H&rj?-zeo0DgtV0=xk%1M5} zzuTyOb7Z5+W=nKOWT4;wU}dRNX8@Vk6Z^>3d$SwkIzr&d&j~7DzvlgPH}u%9v){FU z$+D72Wk1;vFhguz?Vet%tWHv^*|h&0m}C#oET0;~mW9lSxHNP0YV{FvD%t7=imOmz zPDZg<12A075w`z)agf}ek5a+ZrhHv=0)v-a8UwHTIT1c$H*(&Ync{;j3=Uu}x~)4;6Sr3H zE^)-tlgRofL~9PGl()slt4l5&bkCWS{e#4?00sJip%YD?|^EpQ*=F1!SjiBNsri=kf^Awi`2$T3zYHZVO&e zA?i$VHb85IX-B-HW*)O4k#^bt>uQtsq7QVLByPfAGg{6Hi9LUXIO{~`%6Nr}BL0XhFAnMvK z%V5@q6z5uZJCFxFr)uqN#AbX9P@kZ8JH0DE0xNjNMr?0S`XC-Ht8Hzn8IKRWoP-lo z2VPp_lat`sO_b7xyqVirEUF*~u25d2G7TNiQFlt{$^SOBrliDj>XOi>?*8VzX#%@DnQV#uX|7_PZlU!@0 z$L5)waslDCCMLR799}`C4>~)_YciTAI^oVAr@g zt&T}N9atNSh9HZ&V#ZmGMs6%i*b1TnK`#c$y;y?+MNg*Z*!P&yWv^#Si0o%za)*RH zV~zn$R9%aqyW?&Oe1M*re+Kxj;#XHlf>NSS|1f@E2PM`^p)%4JU((VfNuuN%R0*o9E}^n)25Zx!FEMGs zs6Di!kk-@8t1@>zC@yOj6PCCLFVd{4KWYTijEQASC;hVE_uwEND30hZ0i-^mb|X2h zV^J!B*wsbOxctf|HoZB}^xe)ODjr(09)VQtK<50_Zrkw+2<|Lf;&UqHJ{Zz|0z*Tm zlwC8S+MW;eDn|Bu$+&$9d=u7uBFFmwJTf)(7&M*!zA82O<~s`fyEFQ~0IGuj!BG`5 zbhb2BadokGvNW{$r?Wco|F&?*DGabuiWNi@CDWkOr8@11^>Bm|Bv6#0e+9I?m^lBz z3d%@bF1q@l^=WXU&2g>#^yhnoXxLy5{rS^^Af>Kus?+z)>G>?1{}c2YGAaTn09gon zb$XJ)Vg;>%O;H(dY@2LL$+}VX?@LtvVH&9LTZP@}r7^&OL@NQ&thr`D->Kp96oB1i zyD4!NMJ;@L?$$X}V74L@X`QCZz7gTj5pHnEXyl8z?j>cwU{N2qU z$|*?>@;yF02AH?DDXoQ8s&?GHq-X0i&TSbMpKh3|S!n2N5{>jeLd~QiIa5E$4ApXT z^H)yz@M(loZd0wB1I~5BGwl9IUG>}-25=l&V2{yqtP+EExU)wW1c8Cc*E}yy?O4R! z$W4^7Cb6pzv+tmjHK>H4lJb~hazbk?jxIG=t(Pchw=QJvN2ir|s>a6(X$cOlVIEnd zc1ovMtf?5uN@x^;PF|)lbQ)pG+mZWGBwvh_PGB64g}%=vnp7FGA;-thwe0VU&~>&n za3#|5Wz(T$9h#cNKAAN;*j#QVwMsPTcqGZ9Dvhl~+VI4WAMJ*cFv^cIxscLyIj$42 zpMnZe2r7$}7Pu;#oN<#HVt9-oW;GT%<_}v^ow$c%IhAwmaQw=f;`gnm1b?a7!(=KR z*R(zx_}r3FWLB65)RZEcuN9g!1}~v*3>~FRJ0MiDKgk(nVqeZGN?RgK>gxtHB*aCi;mm+;!AAte#5YgZIVQn!y?t-)5m za7z4C^H5{fLdeKyI&CCFccJe%D^|aY!axRCRDvHX!sSe@jfy<%V1*fYTsmJ7iLi9k z-hZTVP-R9;HqP+Y==;Q~zBay%!)WAJ&!Tp7b>`NAZ0)us-A<8U6fnPn&z|CQ%^KVP ztd6=Af&zP*zT@@+@#u^$PhG;q#@QOWrbdQ;h4-R>H$XJx-%S^Rdz%DL2mkx~>g3*z zQ)=HX2G^QG*&`24>CP^mV&&Jq7U75NtF6nXnKTWa_dK5OI?Be-@~p+w#!|}qK%cJn z41Z0u$ScM$b1rqRE=^X@Uh~6>Ahhyi&XzqJywd1 znJKc)9~_sNqSG{}M9Fc%fNybbOkbE|@$3vo!14>Gik%By5l2GJCRrt@8j3}V zGGc{b;cKcb&07pChR-ycmf}!$*g(vT&-`ls;UJ{Plg>&F;4S*DQ)xYd^4A9)h`j0F z4v&bLLmWWGO?k?G2EhaR-d8bb3%l#j(qi)D3gaKu%zP3*yu6GI0F{eDQw$fXq#!uyAvA=J6(&Nnorn0L@p)6Ri`VfJ|~?^z-6OV}b#j2zznN z5{xR|`^c=;+5J<98e#ZNoyk=iTTQKlwcU|`Tc2wz#0g#|l-c#fQid*yHM1y9mf2Z| zY#+IndH(4fc&rGKy>e!|OXSE{UU`drv!|@G2sOr3DTgnHJgv$49G{|I(+zic9f8DV zCAinvk+Usom!iHG!K9aWyNbalI-x*s$;!oKa#B-<(V$ao3(cEp)qs5RN9wP#>okH9 z66dBME1>G>k*>oe^~|cMBsNeGwT47ky(S`&R~>F6;x-PmWd9DArAvz@O>=hSn!>e0 z1%wFN1_}VH+(V^TRI(|^YW`OKqd&Y_hp&^J#l8%_d2 zQS*z_H4pu=he&j|a-_B3lSo)z=YA@7q(R2cA6Nlc|9#T_8>l=rJz5im>#4qj4&(oybSG~DjUFBn0?vgO*kjb zguUXO7QbX5!8@|lxg^7vV_BGg@&fB#!kzfHl~v-zAAV|ThDH|$a(VUaVqBpKb^rNfD#9f?^)>8 zNsC)fcz3xw;_C@RF4P&*9$ws%jlW}#5da(l6#R}E#}Rtx0grLbqcl9@-5BKveM}PU zBxS&O@C+bm)v(zWr$bMF{@Wc;?YnE#7@9pRgcondca*4eH>68xdv&K&;w;I2;jYF*&@R?u(V<08dn z$F^t{5Na1aq7Yc7(E=vAyvWI@-n<|xVj*FDb}Ey3>{rUnO(Z6gR%@h5mKj;dt|5Y; zIj9}J{?j!7{b)JHs^J3GVg7dArNcj2&Orsb`^p>I6n1@S7njYokqw$ox6E%1>r_nF zs=XJ;X_n|Veb&7Z#8E)((0W{5Q8*-<(Un$Xr)bYVE-F>nlkJEcaeSOB^_P2+?RNX& z808$%1PRMhHMA{Ul}kQRK56VQec~Ssaen*#OYMMxW3jj^|JBB>0^GdwbcT$ec{0u01nDhq6j)uVxYd6CXbp$K@#>-ku^6(0bb4#LMES-T2Inq0`4}`U1;n*7O^q;nw(e-TC~M7x+rWl^-vb`U1%2R+A-zC1XfZ&OxDC9 zbE_@I@*>xAQW-NP)?of}uAw<<^$;D{MEPNaMx9Y+WNA-msLGejm&2C9Q%yjU%0)%N z9}9O>`)+)&o_1$raqEuM2N0wue*6KPnbC0=QtkeA=cbgkncQ6FFpfvcWuK*uODsHz z16M356BnEPV~wZjaRUN&=gJGDo_5MGI-VXAmt1f#E9sQwtp|B03Uen!_7V>NGmRoIxQgJM~y^9AEdYwPgyDq~q*V;i=X( z7MtuG6H4?WY@ch(ZKBTB)OiEMqrPj^QCw}l(>&ZMjE-aV71mkyrA^OidZj6!6Rt>Z zFb%jbm9D~=DfVPx=gu$cDGA0OHxy;DCUd`%1 z_leiC7et9ZC)<5F_^{$w=sTU9nm~iwRgU^*(6UnIxRI%&H(ub@jP->#L{iR>rd@awcbn_#lR!m2aC zCYq|z8?jK6@3_0Cp*k`9UB zx+!MT%A2z(a=+$L@1J=z*|IN4G~5sfdyV@k*DBW@drWgMdl!i_ zBH{UdG^PQ9(DK+a!4Q1b*dyZ@$Z9!9xgkR;h>Q{Z9i%~z z>;M)sryC#(F=44je$PIQ;fSs^6pmrTAJg^<(tWd6TfYoAK0$u#U|ev~$7|T9wdT+v z$^8#2LaX&>=u=q4EL}xlk46o4^4^I8b%hY)!z43)bztOQF;&EH*2`9J5J^4bcV7*} z2r%PFG{6t63p+8Qk|58V^(aCmoSon9s6HNPS&TB*@+M9xe;JwR?Jd>DvGyW<~>V#V|IWHu)9F`QU&S~z2E_qbt zuN7C-R#!(|Swzwoy&A9wQx^#TRZxh7w>@}BA*mP;S_sPS7xSfK;ExZQin%6QNG08> zGfC(}KG7vCoQfZ0MZKY2_P{zKePC?iroQKzSLZlX&=(9<3#^}YBzpz!^1-IxWq!uxqbB4(Ao)fCX^~>wvW7Ma zYF#-J>N^vLI4+>QgfA1#yo&lRpuE(1RBLbg9Y*}DW~N)+@nBu{aJ6->% zgFAJ4co3qVilr4?Dw(82(=6OhaT$7s5pkQ`|3JO_%G!E^bHCTL{=9X=di{&7p1;QP zV&~}v3*5*F2_4R&(;XhOYIs+DsumS9~ZJJVluGH?- zgHO|?cvE^xP_3HBrPZWP zVk!RZD$J}}UUI-v?3+b?Tv1t`W2P7kC-C63uL%)<@ z2Kmgar`AGkgGXbd_3^3lg#+6kLD&}tn(uxbmKb7GnpDr(CC~&5a9FE?1+3Mwi!0@| zV2BwZQdoqwm44ukhr$rW(8s#4h+3>#XrYGJriM`=vPpiz^DM`-x>?8@OnsQ*Y z=Di67`w`9)px28eJA@ExlI>ak#PtbwgBpiG4XhSxm~xyUJ^QA_Xr*Nqy(7rWVWJ*( zgsaUiU6;)B+l*ELusCP^;vz>!Q;4$C3*6w(0wS%Hq;wC!8*pLc2n=b(F~*!IJP@L) zi<=lb5%N_{fQf4+8hx)X->`Jkl_`8F4KYm1mP+mS_Ueq0C}et3tg%ICcOVbJ6oKHosxLc5==u-?T&W>`H4<8*(~>FNVc#PAnRycoYT}7KHAE%uxNKA4BlWRm zA?{25E2&s}^AsLodn?;FvB|5K@T>fF9S1&mbHZn5TEmB~V_+Vg(lh*|(%2iDd(ix7 zfrKH@Bs{IKH4O`Pr&|?e|Ep?#0rkv10~SmUG0~_RiNAN;Z2VVHHJkB{e$=%Gvs;iz zylKKc2u#A2=xE~~Lz+FR0`$QVuc~$x3I1*etZH^l_Yr`$?DG`jV+Jxl;YJd@^d7cX zsYghO$55$3x;IKBO%(ex+1Aj}*?5!e9{de2apzIc+b-cjFU zT_tW}8C=R;Co+C2#pdja3?jDislTRpe_e7;c}}(*UHN^!!*nBPD9wZf1rz{$VHr$# zyQ_K0hv<)y*YIU{cm`R*o$^uaP2Jk+E&P?=|FmT1^TbTEj z`T!0G>z$-&vybbjDgb5XZ&_^BxYoKWZ)#;|1rApfG?*5uU(AllB#+CZ!fT^8`>iS( zd5q$93&7C3C+39BP~qI5Y9^r)b3qK69BWctr0)z`^u$!uBze%%yKp-KP{%REfc?wG zR=%mRg#c1As-Gvj+^IqC2c44c*Ea_jaB5 zZYJ4dfv`(Eh2a%a6BeT*ik?iAM8_O)FrIZdW;pS;@-6Rs(Va+zZVx-O6ZS0yVgn;U zVKs{HOfj{hgf7UA;U_pAA@5Q>$cV#>1r+|g+wk;odPp)cHF0ElbJ2DyI3D})B*YpS zRd3s(VzN5^x^8MIj~0dUVD_kBA?6--=Kw8L(E$wIK-tuW|IjeTy1=U;4b!ze@@!_e z8RgcS)D{$EA=iWAH*h9TuV$ua8Y;f?6 zrasL+wRypmdjaPpR@_7;zDv++ZP6~6o!d@HIcW~d@>H1qp7xth@H&o!Uo9TXAceOg z?i{}(Gyg7KzYitw?o9OBSr>ydlx2xmRI;@bpfOK zh1*kdFjm~69{A|kC2Kbt@f@aEsny+0;R4Ekw{kx?u=kHE0AgU|a2DBdsUnWgA5CKk5RY+UK!UxwSY zFp1WU-^T9Y@7Vp{{J{SmxBnEgnM&HLd6ux&B6A zh2TXBW)|@M<~_!-_b(xr0+K@tn=_$qZLkB03wzL)3>7$QM|~57@^GqQKavNjd`(2- zpik;0ALHj&Xi`{J6z=-YVArS>?T!Q&BOAQS#V#ni&Ez&^joBH3CvdR{QPNpXR$lFey|EV@iRIyfG6GP>-#<9T_g!~ZzQs|k`e~8r3Zz&9F zS-DI|)T^+!+T$&;RLekAyB~XCvaY{Sz#Nm5`tI+0EPuLRC4-NsT=ZIlaIx_pS^MK{ zt84Rzh9GAYVz1)2{VO+nC+%$E;Lu3fu7%D0xpVz~y>$qO*0ZkdJ25umj`yoy|;I=48wQVTEC`Un#oAIY6v6+ z;aBH)l}w}{I>=J@3Q@?@FiZKo`pKxEJ8nL2RjJgeug{!yFkfg+4~_Pr%C@Fw+Z@^U z>$Kdds-bmRl3q2tU1lp>xJO>-Jykhijle=O+o^FK z=fm7b(o^EoXbj-9ezmJ@x5hj^l;q%k;*5L+xzsFY1*fQ9xQntNRL)RYS~*)XD_4{{ zv(Ekt@-YpakSFgi|1%{aPQ>pYP98FMKx#Mp&$s+0OX7E{NO@}^n8WnAgq^%NQMf{{ zC>X*N2t$XPAFt@f2t=X7I5PO#UYtl!@^}USGcF#1vUhM8n9$)Lmz@I$T@XNE0otfg z^HRo`q{n;np;ZR>C=zpaVDTo*vL0k0K__(37J>mr4S?bwr>w^s#TiCH?9p(yKJi|& zWWHjc!F%hi=Grdk!Z*Z>%=H*s+eir)v5CU(&k*Q(5Hh|*7JmlyfoG+z{>9Y^CL3z% z^c~Opa6mvb|2C#QzZdS>{!>mb{FV^^V}TjGWQrtg8n98ms`44Be+sk*h&`bQEI@$y z2V8w&AH%i}igt8Nu0`6+ zNrquV*dmpJ13D|vcORV!OVZ_TtBSt$Sxly&n2*H^MkBSEP6Zm2+_7N1Mp|ask}$Z& zq6h*)G4^YNHQZ^N_oW<-hI9zu(atDB^NUmMlzw0o-Eu*jaiaD?Lualc>_p}`3cFjb zeek2688@^jJxyK}9U9;!tB;qJd65N`gVILo0`?c8+TNjxLyQo;$=0<&CS$>Am4bVH zN5{)r0?;;>PTjmx6Vw4K-gK!`TWP9In`As{wK5Z~Ty-4yW(~Cs1TXam^o9(c@qA|t z16I5awl2&ojqN7`9$KFZ_^b2ca9KV~&z}}6Al$>tYs~jl*uZxU(v58L;gWMKjn5<`hH_v4b}9mM8E{Hukx}ZcWY+E zGobb}OtPbPr89wdjZUzZi%5IrO(hGJji8d6LeTBT1&s;zGxpZh#Zn80H}pF+hjtxF zjYTUeAXkGj4l>tPQ%Vc9<*g=s*)YY9?;ncK#)n#~?~N`L^ez<#U>=2YC$ux6Oih}% z$a=f5q^l%EI@xSsdYH;6*2>%6?ad%CwJVm#j9c6edK0Bb9L3$;h!{C>#Ty$?0vdxv z7YfrRBecG6hdUvJ&G%ZH^9lx;bcQfnv0Ynic=B~5%~~3RXE`!Q_rYI}66bB=-k5ee=wTy8(7b^TEIq^~JQZwBsd>JqM=+OD&euNWPyeEcWnyu(f^B2XS&I zG`4?=~SZ0Ox-euHx@m=#RZj`vovK>dg zT@IhT7RC5dbYUySbskgW6_Xmh)WNZUdrfy4JvXM`nJyu1B|BDLVV8cww3ttj}6xaT8S-xAiUsYfio89Rxyp<+MmuSVhcT6F(X(G#JgWRgsWLXqfKv1 zHG2qK_RFbHJcaVnOKpIdxF@IFCE_4g7g$f>9`oCnYLvHLzA3Ip@m@YlJbT`OnRgVC zzRjBNc{srhJ_Q5b&*N^()eBf5Orqmt2l!-0p=1SUsNc?r?NeLbv`AKbt+K>qVqmDD z3qZW2G8*5i3HZDq1j}Gu)8o_80%was5Okt4w2Eex75uzYa?#)tK7pLEwh@j;qQOmU zV@ei@2va`|x0lfj`($>SkN_6Qrq6(Qd}J=+Sl5h|KY^%8IJ*ui{tDA#lpDfe%pzcp zsnCWI(1gNZ4w=vfp>dOYj;j3?O5x&Q?qxS6DtkTR?w0##`Kq&xaYKek#H~9gH$BEA zOGf+ucp1>VBsTt?mXPSOhwGT#5uXS9K|?$YGNF*{kyHVK;*BxQN681==qFVyFVH@^ z*a0G5Z(5h>PeUPxpvV0PFP*FB=Ft*@Y)CO~M-2nJTr@j9Ue@udDj6<*zDmN6cnwGW zm&J*8&(qsSP^f6}KYZ%#r(p>a$#UdX9jLieCEb^E@#i?uXH61&ZCpa0v#mk5&pL?M zIU;RAlS&wtB>Sg2Li+QNyk*GPUw%Pe9jsh&2F!%ZEaua6JYRp}Jp@Q^Vm=#QOW{8} z;66OiJ|v~m!aq^n>;jW`bZp5FM<)grxH&KZ3cq z9Q~%}o+N$cdz~8lR;u&Mr|}hxKcz{41xm9S_rd((!i35~)p1g1)~d^SZN9yVvgli| zAuU^b?n>I*x|__C>ditC62MJX+Bl39OfJ+6p% zQO$hrit9&V7EzHCRac{3f==(_o(Lic6}V&E{KpRqHQT`c z_IYYn;;)ETRQpjm^?NJVJj=Xot|HYei>hwWxUc#!W)5n^6c*aKO!VVWg2{1`q!uV) zDu82_$XF{d5lR4Zu0Vif9B{|iXyHC$FJTFx3lm4-F0@!nVq6gw1HOFyqDR{Rq>O%wcgvn^;oMhQwjh7(> z@7vwt-gUx70eusUA6spK@fOz@VkG0MO&9s);mD`?Q|cNMn;;TOl0}lMh~c7=O*F}s za^#8Q>5zVBD=mmR68bOX7CpVEj1?GoU^bzex9juwG>9u87_Cq)#DG*myxyVt7vXwO zgt#J^5xzSglJF8(wmrlR?Q;S9?vpebfYU@j1xnlzk%?7 z!++ew;z#jDC@Xd~y=$%~vPJ%ywQ8ns3SP@G^ews~|L4vSU()$k<+njOl<5DZGyI>C z_@A*ip<(HwJ%H9}T$yyB!KSHz+%16IJ~#m$i5EBAm@%Am(6455j+kNovZ6*K9d*Co zFF+xy-2?|pp4*&oNsE{SOjxfeA#M5nU^LR*XMA2|R~3(0au(jF&m6xmB&&ni__vzItU#~RP^J>qXdnX+m{m+%S5g4DWhWLwv;6IHGEGM#7Lb{AE(AhHC?df3SwoU z0M=YRRppoTFt{qsYuNbk@}|98phRV?l7?k_@^CNMl*F<)TB6QT8YkXSQdw8IF}J#L z3J2QeeqLsK>&8_Q#%GexDyJoVHcN^EH&kXN&f37X0zn&bE=7V2LwFidMRSw*TD+nX zFO737hO@C>fG{UkGP*p6e06ZN|K`(^v$b{sH~+@-Lk#9a*?qww+$y6!)J|-7PzfO^ zS*FR^OZfRtJEK04hoX6>V9>TI)6+UL{&WOJ6}lKw>=4<15TlXPlKTa7#R0&NesOff zGU+0R@?txGUI4^@dKx~It(b+rCl8~vTju8A?9Swre4f>#G)ZGC2R%zCLR?YmC>s7F zd4RMK;B-6Ud48FrZ8LvTK)0G1B|3=S%$h?2d@3k=ZHnP%6diAuZ}$@sZ4PG69LIB1 z5c*-6V!uF7h^-{V85 zc-(82M^LXu)(eZ~!YX1-?%Aflw2phLt{2?w^S?OO4duq)YKQA(!$a~vSPL)Q!nTJS zXZrsj+pFfUrmcMb_@&>Caqs!wNoVg~hww0S4rgayiUB$j1ODR5sFH##t7+FuEBaHo zPdKZ!HA#2y=ox?Tm};-5?Ojkm-Cp~!2semg`4p<2)kB+ET_ysWm%Dr6VsjjfnOMEN zsiTn6db8I;GM#<-;{UL9j?JM(&9;th+xCua+qP}nwr%btJGO1xw(aEPt$S|OJ-1F( zf0%z@uAXajkMXR9jH&9?GC5(gSrpjQttPhV57?-5RI4F;%VJW&V?|I{3IwA z??8fg(vZz;3a}5HgH?KUS#PWoAS=Cr7agJd+HdXbga?xwOuR$*9KTRO)@1)%{7=1- zaZn4T*o4?@6j;Hw+e02V z!w)$6jW=NP%in_AcqBl3nD|3WZm!G$94)0hD4P2XW>V(WDi|qiD32&iRieEOl{3Dg zJ1N&s#|{&v`R0tUV5Vg}j|BS6XGeoW7!kt=iM0D8Kn8>O9kr0qPpO%sh(Rf-U)Hm@ z=n+?18T%v>V>)zWt3pnh<^JXbbP@UM~MBjKr z{q*Mmk-7%FR1KEG#~e1cqyY$bKZWa9^UMzOQu;W3*Uj$KRpHd-&+*mLzC0tI8mvgB zXgkGUymZEl8e`Th?Cqo&2;!3veVE{U<4T4Xl7rT;2U4YC4JJ8kdAQR=A0-MRzj*t` zh-eFlDC)uT-$;5=ZcKn4*2>N<0bDL0g=7~UVF?oD@HfoVJyP#KNBJC71Z;jOBcoG# z*SB5Cp%js&%)?reSfQOe1S5pxF!f*@7V%;P_za`qgmGAh8-zOs@i)QVqXavkZ^U44 zwxjqgqhW-8lLUS^_vA457>9CLhjI#t!)W#U4-4rP{cH!gwrd)OGm*4n?!UXF(5HCY z^rft`UCzmFWzP696Ja}pyx84tx&&G$8spW?t+eQ)a~h_Md88*ERHFs4i_&k&m@RA8 z^JS4UbA^@{7MjP+t<@)|nM$1!=%F+rP=ze=9ly!Po`c4~y63iqV1E&ZZO|^b&eFqC z@o`7OBjzC6^#+~EeZZVdv+Hv3@*!L2`8^&rJP~GmWjWI|y&!(03=(}&I@ zI^7d6han&S@uh?)_3BFo*#36``UG@CD7}Vbn;;g^8yKTTs+FKL=)~iyXNePAxowmY zP@8VDCQ({ZAzQaRDL77asXiQzOHidWpgBE5Vq)*TakLk3riG1MPp9ntf&Q5YPT8u} z5pWl5#GXsU&=q7}RWZJO-4{HLzq z91k{%1~Te#)a%uF&f1;w`X;o~boTt51-NhOT4zp>j2<|>13}3e+kf$)YU*uksA_oyp|Mb_JQ^2K zA&Bt6m15?Avsw^Nse)fThB0Q>EJR@()U9U{>G8lJCH8bBw*-rKRk}xx{08}oR8`I# zZNriUb&hQqW~VX=yDhgKV4i)+&Uj7F-2bZVptpwlV^kE`@bBKo`o0YfK;xd+PASJ| z$Qfp4u;rMb4Ov4pCY2u6U3`uvjNMT4NE$5Y<5)%+aIK;uw62$Fip^CjH$5f`tcNfPt#TCXi2cu8X8QxV|->_`U*$@`k63}}?CdYP zL$aP)D3W$CPu;R}Q#lynFbavphR-k)h`pVmh~Y-lN70yM;li!!Fh-4}jiWT;#lmTB z6j?N^7YA?kKHI|U+}={sIWh*!R^nNVmWS=sy>EZXxsJDek@@!;oUp(i-mDX^IBo8< zreI~C+)a%81>AC1F#oD{i?lGi#ATLJ$5AG*pYyz5Xr)}cG=(oGC*tJPnoWWAz5qd= z#Ef6_$^*ZnYd=A&zSU6ncX~hkzz=`;fgj}<)_NXmnG4U{Wf|WP-%DX;5f2}OA!ZSc zU6oPp3^WF*uKUM`WL402{8W=43^b;>`JpLJa5d>~FWs@5TxA!hJoMkWb>dTA?AFR) zrVHf$m`q`C$TEmDE!oHfnKnVrR;}Exr(8*~u2k=<;W^3EO%$0-N~F-_HP-@J>eE>o zgoLXhUKv2ca&U+D%L*`y?<8=uQFz40xfeX(T+el6pr{YqmWth&>gL}_V&wM0$@1et z3OR|eLKqfuM=b%TxMm=srmRgv+8VAT8wI{`gecd znbb0HiJ&tJVLJd(gSZ+1CyGw(v>7v?9|+e5y$qjY;?@#=P7|87>6cisbO zjQ~rU@Bzf)g7%bC5^!RkfdL=s!10sg4~dLRqypuzip2fM8UTBR{i>ZF~2ZCSy;eU&`cC@H(t5IjGK6k@TzQ5{pXT)`lcd6I1A{iWRe{>tg;?PZ+fX4fx|r*E=xW6SF~ zyQ?GX`~B;R+@D-MvQQ|0=4o8?%66)}19jm~3v7)lV||L~R!b)aNIw>eFbI)T+rFf& zOg^8VAt$VtH~KE__W2WLoWZo(AwvP zwt)WbRE4F3a}jyu1J#z8?HI~$#Fk{>lcAytJp$g)^NNYOP`MqUMa6!Tz;X|tyd|B5vtL^l(qcN=q*E4jFGeji@Y0g zxtlhgTjD3V!4wrRfHR((6OO`%|P6;e&^ zD@*Vg^XbOF6Cf-+Y z0eqOV*%=DEP$QO)o8&qkr_sHJ2g~l1W7@$6??GmT?;$=@+8V z4_dA{wYCK%$$saQzS^4!zdAe%B2`sbRyf*n3R#RL&%ChNp8JdPW@KXj z>!SZZ`a+DVh1P$Th3KWof(r28r4Xd5ZNd(LjQTg(Gx8Uk zHLch>Zd`X>=q>ZW=XkH+Pvg!P+{grgAeZ5p+>SS$W;|v%Zg^h4A8ulL0J(#AfGGqj zLK$(7ZXp-58BAm3=W9y^2aw5)ClPP27-<*QXywe1OF&`@3z25 z#bh$gKm3LYKbg`)Mk5n)p+bu+E+$*Z90d@5j^6eKeTac9 zi*e&)j!1_lYKYhcG!FPyp|4`3sAl);!@1S6;3}i-RI6HX`p2{?4Uplw5mLx^5#b0< zu8tig;O&2e=fHGOc4&?8m?J_ACY$`JEHw;VKBj!xNegFlQ^XXs9Q~U?^+@4@V<~AAdVOA}B!E8_wR;gs zV49$KtvBxo?IS-z2;o<^(x8L-Nl1G{Ra?2A4CDRh%;8-8k6O@Vp2HKOEQZk5tD=a49!~4_f#XK z_M&9!Xuma<+&+4<>9C?ZIwQKHXvRfl$5z zN!m)!)KPIA5QD;nM+!Gde{Vt?Z&towhF5krF9I10=~qJMIFCGK*i>ph8&x>6?GVpp z!i>vQ4FqxNqQa%jHoh=0I1tO0aBS-Cf}mwCei&t7==^Eiuxa)98jWvuV8UxmM&>TL z6b2}>*Br=>HPe|`l4^cW63sMiq&$PcWSZYHn>lmGqlZwIZ*HyhR5i1#Q~e#Q>i$w} z`s;mB&GssZOG(2RnULr4Sh%ScMU^MTV=X@T}@)taj~=!*r>NoDCRyc^Vim7h{Yk}$jegFt>2 zUY1tD(NEqKHS=i|5nSR_3}(f);5WCS#I__x1QkpoKK=Il;eO+%R5%{i>H;ApwP}0X0DH7&~U~i{{1~5Y5z4ea!|cLZ|Fe*EV3$=wr;e67S_h zlm=NiOjT~m1zN-sqzvWOc@nkH?0Am_aQDSEybn?-`EGZe z(I!w>z6OhJGs4s5x`XjKqBMfm}I$J9a`5;^q76u(NEDr2eg%#d- z2~`eGyMTg~$qp^dx1 z%R?Y-P1tRMyE7WDf;aX6uZy|(uuk`hR+jUjZVrIkHwK^Z_lak88^Cd2*|p{mu&O`q z#-`3&+%;(&Y`(Zn(e01n7j^C;JB0(O);kVMUX;9t=j6`Pym?1n@WvG-r}x42K;wF2 zUK5gEA$xY&n7_dPXU}MinmN*D0|3}>_=~sfSEYFaec=OwP_3$E zN4>07*;H*)UHx3or*v`m(QULdJw1JG%HjLt$CoN?y50HGRrBJLgx=$GSq8w6)O7+1 zH3>2hNHaUmEj$3=wdN8Su<+j0UKx*v<&f9d8u45~!<>h=BuB zjlc7!!pNIF{N|N47T$$9PH%fodjqi-JxdGt+cn!jSSZoJX~-XoUUq#XP1|pbP_Y`^(_zTkgmkF+m0TCok(WuV=LnxmMs0_j#zAmX}RhGx! zlQyo)C~v3+#1`vm& z_p&OGSQ?39F(IBjSE-Yh&z`-E1<{~(I++FoW~sP==C$3hiFLnnRs{p8|53mg8BRtb zNvukjJm^B(tTJ-CcA_LNEA ztMED-xX|}qvp_}qztfw3r0z>1TR|)c8`-80v~z zS1nL1i$Mu!H5SjHaIELQ_KiQfF{Pd}xn0ugi!KLX2$SIx(Zec#GXlrsHqK2#`OkHnQ(V5ja&TWT`wq_HUzo^Y{r3A%A(&9u)xi!uuDd& z1iNX^Q9wt$j!idhOb#w?pF9a%cnZbA>j1RdfSh#eNTAnVH-)@m;`?*BA5TllF`4XW z$wg~IRSSKQ=q@K)`fYv`p|}hfGM*^kdXO8ILf(a?mZo5mBLlPVVj$gW40mpavxLsq z{m{e79u4N*1T=h~Zf+E}sJ@|uk7=jwS-=Qnv@l_0klbpPy$-|R-ecH6k~{mS5_E2G znLIHNqTeVwWGFl2)pw=t*2wOgh5K-Dp4Kh2JDLcu1H?UG*E`ZrYB<6f%V*39tvjHu zu-H1C?Fjg%B!sj(2i^N$8z?csQGjGNWZ#TL3#^*=XO}+ttlD5*chG02^{&u}jIEW8 zV^m?!oL+vCL~I*r_XSd%t)gVM-4*Xq zaFF5R$cdxq*HFlwJ{pQ@bsA{Ul`wCcrm3mE>1Xl9IzNb>qo|x-o9P?cSB!50r{LE) zjCU}&fC5)w!ausx0epSrWS?t+a(nb3$2hgbiGaxv>GfI4?yNVxUzxf8LX)nTWSeJ1 z5?vuo550d7zHR&X+?~&d@>L^MR)O)eZb1VQ52FT^mY{zEzuo|DOF*}7@rAcmHZO1Z zL$LEOF4t|VF09ex9fZ)XtslaKBR}<^yF=~dvlL2>KQjL`(@{yhA)$}lKtxNzU32RV zu7o2tp?8ylM2J(wRbPODh8rLXEa@7ciV!>82lS><mg1@0r?hXa(jy{Le&*BZI zynTJ6Ve*3&5)Pt6;3ROHMLUHRBXo&ElcVkLz97JuzBhul9tzL;vNnSe<0Tp;?wON$ z21kdX6d2pUfN!L|2^#oCNr;v>o5$c*QwNs4ZrCWs0^x@f^>wXsuCqo113pE1d5T3@Bx%0X(rPe#OGr>I z2<8%%av02u#L7fX_zb%uJL^`7SXsH8wq~f}uthCnLXBWZwrSOqmzk#~R=4JRevpuP z)lE%S~|=P~!x($Cpi;=u3<#}H99NZEKShza1I9uhzccnzb( z*hLR>q(V=L_~2G4*oTZ9vd9%c@iGzCgeedxk4EgfoP9M`@7$iHo^A5#jZ0v9aOyv+ zgK3;oL>r@L7+m6WLg`rWTcx0R@@K28N!clk`{A)i{60HGW=?zx2zhEVM|9Id)6elv zf0*|EO|_V`@%4ifFmJAA9(n^US@hWn8y3=iAX}Lqa=%Ur(FvAaCq;msthhQxNYEWA z)&Y}p2{<36#yf-yqqAz9sr z&pNzLPRO*WO1ljFB5OXw&W<>}=<1T4!P@Y_-Gdb<+29*#tTNxpWg3$L5q;6G4eKQ0>1thA?d;o`Upr?TtE3$0Z|&1vmDOz+t#Q9vM25W2 z39ne-K7^f|WB3+EeoL)NUR4UZ&90VW`|Z4V_i*hx3VsKSe4%zVTBZ|?HYE;9Or0!H;m?R&PAe1ZP{LZ42x{f`s&vcOgzkE!=6($Y^-x?!;U4v zjo75|*3n&LLg`|#1;10@pKJMw@leZss?fAq5!TKNzC3c&epnG?j5?Qv^Bk<9X*tsi zc}DlBUB}Dc(}l7K9s=0AVD_k0Tw(#MC z-*iLL&=&rX@$?rOSx9W=R-al!J|JnRhaMP7#@_UWc88@(3`M+T8pu{cMWxP3jRmDZ37k|?wUYf4A-)$cwp;j!tw6xglmP}j}b2@5HtYb2FP}uheze!qDxDoLSjc2%+yf|9= zs@5JT$9S&k(bytK*i$b`;E^n4MQ>54fK#6>uitTGAP}f|xp<0Fr~Uvnsc@_ET;Ln` zsx*8z&OUjS)|qEG%^7&dQawllc#C4-_t7rBU~V<8PqhaMZxdJP{3c}hf;i<|R8w7) zGP9cCI2_E@$qezq!%TyF4b)S^Qr{=U<Ah57h_#*;PS6T5xU-=TfnlJVG?%t&9lRQjlG zAxYnOD)MNU@jgyLnK{S4u2rm!?--~(PaHT1h(3prjU2opROo=UeL~Vk zfe+)E0=o5R*M@p&y;PwXxo=BpesE#vd9M_JD_2{(;L+xMha zxZn~Z#K!_Ovpb*i>S?mj(+4cxp)NF(xetis;5^OKsf#V z#!r0}TEZZWg93QZF_%Y$DAzk(=t_y@D&>yiu0-S_lHR7RMiuTE%qbHCx~ny$Ba z5pVC1Jk3Xm?!fH|$QmeNR%Vb}6L_EbV!5&^nxTo#wD0KeY^{C0@axdVtEm#|kkL}x z)RUm-wm!7vn9WfB4nGMqtt7t2KypwB7opm;3gueptYo zf7G`)0>X6e2`9mbq%^*;gId)}ml#~c3X`ULA6;`9%z1&4MY<2u4{pJqQ=L`f`Su)^ zBKcE2j0kYM3+vC%`h#WuSo&G?&v4VN|Hxr8{}Cr+Jy(rjRI3bbXR}g${q-gX_o0|c z4J!);Xv1`LeLn8!+f{U%K+sTIl!hcv^pK~J00s{TI!hXK)_Fl6VGCI}ILQ~C$W1{l zpamf#fl!q6Zk0bel@IA1$auLZ)!DOeiAGwz_XBFWm=`i0aVg^Rg7QGNvGIx;|2fEQ z!WFlA1Z;Umx)laTN_WkFxTT;Wqv6<_E;WC62$t5$N?IX%fBKe*~ zAzS zOGjG;63gAYtu{C9cWYl(sQ%d=s2YUy;Z;GOo2lnWvir5tZ6D}mCP za49=l!iC@TnqQtveDd5YpPPrOZdco*J2ln6%8Ev*&8Bn%j_2`#CoJN|y^R^KKwUYI#n0QClL3p*qVytuvk*NiJLSzWdtszWthwP))D7sS{Ar+YAj0V7&D|W;;NCGG}gsYMmnNHipx6Y zptD)(o7~bi++M3uj8zQF8S%+;`R(gGSyy+T3mS=&L#e{G9!|F4Fv&9&Z)kN`kCRhG zc*E)LfN2Srid)txHNwk(l#qBI@obQ|%GgjuZakh+Xnqi`7fY8|d>L|_I2rHKh|~kS z>>AxwW1dz`4*Ib4vGpa~43nOl2bgt(lNi*@igBL#WaBpzr5YTv)>`i{3$9w=t|TnE zMnvqzGV;l&Fh+XDOzX!K_NKL(k6Rb`gih*;+B!#=-Q9Y;ukL!#nU3OLOKmARxD=z? z1EdJN!>ZjmGf*31)&hE2SA`#Rz&9(>ITBwDR`@hO^ZS0&5TLG+M2xOBwLUDLVVcH^ z?j`%nUVTFBFlzyjhVL4~3OUM(Rv2BASP1~AW*s~3y}1lt`PnKK-Pve zg-mqe(_%=xgY~f-@#-@k%rxVeN0-_lYfoZ*k$uhPz_7-D38f*@yREMXGj3mdSJ_+vDD-p9Y$p$CLkyi}QC&y6z^PbxUe6h)Wxtm-G|N(u;Xbo#|7i!-;X~JYamj%Pc~| za#${g8^)co!m;Uk7-4H4@YO5#2%=Th^G^a3YW-cCkxEhgsEQUy&ykRsT%#qI7P1kg z4EVqSCAEE;=ZJ7)%JUQz-Cg_G7`#|>`~WP9R85O*$GhTfZQ9?PTmlDPZWh{7OP@P$ zU@WrGMo&!7*Q=Cb)13)FyEhE|fTO$Bc5LlHVG16pyn?|By)}?kLdyIBfylrBd%?Ws z+`S|+g7>b?hqJe6LU9>Mpv2}q3T5MKyH3g4aI_-dA1pl4r-Z_ZDB;;qo5{!W zAi$yd@(b#`Fe6_Pu3WAUn94O3iNi0m&J*`6&8#su^dxH-Bi3FJ4iiAMFqpY78xFD| zbkXs)udJ!A7*flgE!N?Nq_z926edv;%r?z{*lOn3sH-8rCj(fYSn-=Q zWUIw~SUreUQ@W*Ki~3re$PKoVepcRmkti8Gsw>0IV*2%svYH`;=6S8ruQrf*O&iWM zphHAQ!a_FM_0s?ZfllKV*V^UOXoS{utzY(ZS?fu5kzm&Mu58br!=tl-1eH0r=M+gk z6WzS?)P^~ZE#9P(@#b7u+1S8@*B7bm#B%(7{bq{WZ&;*Dso*8Bs@E&Ep3}v9(U59X zdml&z;hw9p&$v{h>=BDk?=#9hqsSyEex{i+wnM~NAQnx(#045qf*<17fD2971%v_s z`MCl`(+#=fjN*k3<_+sv+VlC|)M~~S*LW+^=MC>sc<27!0LS>=z=y#A;9!XF_V0m> zFFK2QB;Eaah}4+7xUZo;@baF9WDnh)xn!IN?ZTgZFp2628sbjHAv`IdKWG9B{*;|e zDm!k&x^aM@dKTDO>L}26cx#ZCPuQvHga*3|DDW~s2~jbL^Uu&zOwd~gJ(3fk)SE)6 zJUZ9_7(o0X(zYRi2{Ej5OvqL;k`KTjx@P~E-Yw`CVb$|@H_7e!AZO(^7JPJtVKI2l zVOBPjuvHgm897Hit+YS$I}%t>FRkbdJ5VplATsmKQzT5n;*6n*s7G=Z@F!;(lttDu zT8M^>00lV#OUZgMy}06!gi;Yr0G3Hb#a`qP(0l2=DRJyR!y^@S%_^{%imO0QlK29s zxQSyrSOvOIR5xwzOX1C|TL{2&;mzDjz)+nb;8&C8UtL6LS`qEkOp5{DA;mjresa19 z=y>kVlRolFs=Odx6P?;xXf(IJdeWnC6(bK3^eWNqZ1tQbaPJTeo!V|rt-62fG|bQq zq$9WEwRiujXD98@C#~Y@s$o!J^#9PcfS?*-J_Z@(Bcu*Mr~{VNBCWaLO!_aC505|x zr%Kf_3s(NtDR_3yzT~W|wvV`9kW-w$#Ut^%)@VP+$lT7}f_1h>Gy;GUL@&V8G5F() zJ89n4h?zDDM!a?wiZ>0#7q~!;rvyF3Zg6%*+i3i_&ul<3go{A>!I-u5n)!j>zhOeP zgZN5^QI*d)s50+oFRlR;0>8nslYS3LMmiNi^}^S>;(G1+{QCasNJ%d8beVu=0v|ac z;3inGK1^0~DdtAfM>z;gM78YpWNZQf2~(vKB7q+Ex01YBK59pupqKi#J3&W>y=qo= zb)8xZcPA|f*GN6B8Vh?On^^V17Z!erM{U)q0rspLx z@AU7W`xtDbfiz{_$`T8c>C7&DLyGZKv!ZIpFO}l8b9_~kJ<<^9-(Di<+CDX^&w%Cr z0BVG?Tm=9j`UIa4!~IXJf3hk7vnT-%)cOsb{$ynmm@1{DTSW0JpY_=0|G1XSJjn)m zC?UPu?~g2;fVC>fyisl+P|&(qZt%83`t_8o^HV)hGRI4M?Wu;6&5iaXT?Odew~VuY zxcixW0|(l|4^AFX7+l*9_}Ph-bOOs9=umuilo$R8^$emGhRX47)a1DwFv-s8@^=Ry6_-cso0s(-Jo1ezEbjH=49cQI3JAT< zo)^IP5qB8G!Or-kycL1w7FEWSuZ->|y9e^Su)5*#5mR6ky)8L`HeEadETX{DnUEg+U}1H=(f=ul{M7{FYLyk82vbHkDMAtMCm2}0x|HEIHoZC^u@HLMcsNRQbB|L0V2{V^rK{lqg9zHOb?Rrx^zMN*&0VIXZ1s3#)r+63I4%Fj zadwO2IWnsC+rwY`*0|4)!SNdkc;QEo z+Pi4YA$#f;l%-!_Dm|Zooz43qWiKlqcE=fgphXw68*=?NLV-pPvpb--I~1|pd8ePE z+Q+tCjo@`fZtfY>dl~xX#*xK6(;qcNBaX1&{IaL8ckJov+@J%Jgu=vtRgxdwAVidz zEkU|2L!61TB5XrwIwiXwXDS6}3e~Pa%zg-a1XV7YdTACMksnz^K6&mMh8&NA9Bnb4 zS6GQCpfv?1m`l81cb@a`{3uc?yQhOW&DDbL%J56Yxg!de zA9x&gUuN7IE-WgAXi1=<5w%v~ZZ^1fzd-C(J`|Q68#}yVjN|!&Lw@QoYgFxt?0$*( zRkMHU;%qnN7Bl*DdDAJrz3Xd}j>>Gam6;KoD(b%%& z_0p#DRBDQ;RH-KvPi6())MB=v5(5i)Y=vobg~}{;04^M!A_%B43JhscL2`5mWig0p zykffCxB+QJaFa1kw#4uN93vnmmjuHj2+3teWWlDFZV9Gmis`9JWC32QaK)DVD%Gkv zL6Uc1j7B<~6szfg=8)*Z@Ngvx_7Tp<6HaykH7fQ})~IO4dhC()X75jFfuWIH8#_jg z(<%Zg_{#5wTufJ68)||b`XAipROK~m8#|ex?FdMSpZgx9xP{jplR@%0(IFx5uyO-X<9IB#_!(yL?cTZf zH~o)?zWY#L+c?K70dGJ|O%47~hdbhd?0uz}eJ0@dL=Abt*ub%3v{)i1eaZ~*k)$^S z5@>zw3b8p0f2%RWMo1}_YLLxV7--162b><{~8Gr&)L)YmscGJIWhs9Pyo5*X{|iciDi(?nY3(`Xe&L> zHQc-v0;3H?IQf!ASQ@NB&WMU|-(K5N&on2gz$h0V% zLoDnHB-RRKJA_W6d@!AaS|Yj9syV0wYK_c2+eG79&LMLL`s!_q_HCYE>EHY}d`ZnT z4wZIo?4`XU)*?&gLKzlARuD%-CFwIr=8 zg^W=xoaD{9p}(LTlKt5m&FFZ=S0Uqvf8dyH+zKo_OfjrHP-BRs>-m{!@@l zJ&KA+K^4c;oJt9y|5U|=RHbW5Ii4(esg>Mw3t+a=i$iVk+S@q$s@l_k5>2lOzeQY_ zope|gt1)16rwiE7-}3< znUhkypv8d`4eJPoe&0PMMV?R+cg&XWOtW#HIFVyctYRu9233g+P+n-XsLnKzrt^v1`?=Wi;teb~`h^fY35|JUe zMP-MzlNf%5=_F}TJCb(h6 zhEfcDMV)4Sy#8>X!Y)|Q4R?FkGhRWL&3lK>`etI+@4uJqMpf@i(h1_(vp`X;aNwFo zXeSm}N~5+F7dT09h_z$~X%Cj3vb~7y7%LUo)l&^oE1XjzmgFW-O7V#8KapJ-AF!i4 z*vG=jA$QpjWi4^fus{E0ABl8UBr0NW;Wv>Ak)g-A4o@Z8nn<`tosCoN7w3eV%P5ag z=R2h*$<%V+m`;JaE?p1gqC0Z*ZlTDQaS8P(k#%c~k#RcfB+$ws`8(eD5cpGp$MV2J zb%>kBd&mO}+|CqI$GtG;B48CS$&?`3pifcVMp>#34xdX8OLIULEIY9d#ZRW0MJ5jUiI6g2-6)h_^mUt!hlJFn700 zQtVooOTM#TUYu(V!=~TZkBO#4OP_;BW@NO1P%atEqp?#^VE`BwNH6fZNi^LDiZ~&2 z=L|zi^#L2C+Y&{x8f(b3vegQL9z9hsl>&YErZj~F;f$iw*MEshszK;%<*?jW1qShB zm#BGD>{_EMYtsxp_G507o5J`&U_=+|3vhl{n&5SFgCV%2!+W6TMgwl;SAAF2)3a6~h`R%)fYvaCL)L$O>*p=?Q6!dsAkoK9u!>}J( z;QW`p?3ayIR&^_h?nR`m#zU!?aHB&f>wv6>w-6=f=VAxmnS_%iZp_v_ba{GR6!)%E z=YhBfc=n`TZ61Q0}!~6gnCdPGxLEjA3T_d|jd#zo_aYFtyAY}4!p`IQvo7Bv#I^n zsy$7UR0t;jqw7w@5cG#V5>tMrz97LvANN5p{wYu@15~Yc+a7x&giAxOE6IxztavVG zvx7zCM)i$Fw+_`hG5=-DbLGes)mm0C&W%PZBC`dKMeq6$?9XE4)#3R3>K4^Ws@;8I zB?kSo-H>~;1RU(@t0UrMUO zv2cTuv1}Crw>5;iH3f_bF`Un_u+yp~+hoqiqO~*Dq*J-tloN1wA7OSPl+!gW$#WM~ zp^DujE?idM@clfOp&(UF1H9NVG;J33Xhu5QJL2y_zK8hLOkNwq$$^v8h1IiPiB7}WxfoolQt;H#j zT)d5LiM~t%*>JFgW|r<7qo%#aIzG;qNWD(;hv}b2p?KWykL-|ac&wm!u_5e%?LS#& zYb??C=|1Fy{&unmXs40JO82_Z3usrxKk` z#7W(!b3l@Ze6oHQel=On8{ zs2vzJBaVgeHD(Kq6AI=}yC)sq2>uRe$c6H=J0S&%vk6Pcl49uZxq_ol0smmwcYLk~^!-l9dyCa^+;q{!*M`sED$Y zGeu6TvMqHFOc-;9fli8h_x)EZ#5@P!XTDO9)+4I%!38YWp_1B&nuqW{V z?U?CsGFvt@Ip-Bs*vFdAa%2jWS%J|e!vwaaZ*Xa~%dJ#tQfQEh)xkce+P2NG$^I8< z?-*QbxMht7JGPzd*vX1_Y}>YNYbQIlZQHhOn>)6hd^z2xZg-!1yT7iwRqv`=>*so( zXU;J>hSBHf;|oZhO}+dLV+n`ibL!$4$gK%R=KhGvD$mn??J*DuS*Kcg3F&S5UJD)X zONAzH_}Q)EP6OdrvK+PGr0X-*|+DC1{00WT4Ymges{M2;!*Yksy~5uhRM_Grm9a)ps6VNF z{Oot?Qz$xs`d7o{hIIVh&yCfFbo?UEm5+_8d)3dK6JFSMkRQno&ux1@&aK@tIzj1c zpLVPtdENuPfxb)#PU6L*%ab&=Vv4LG81iWw2O=0Ts>2TO>2<&s)e~)%;}~#1Y04~C zYtOYiRx7v9(NBh&sWxNw+ZVA4y+%I44@W`PFt2=fSCH7D4Cee4JYhMNU;IMLcBg5G z%@C70;PN{4OxlDbhG)!r&+!iAPMr){thGAR@inaz?p`B$Ez7i>j02wo*L&&OID7>C zs`wk(b!yJshW&&ep|ERYbLrn;>dvc2>ZTb|UU3rYef6TA=+k*i=QWgv1tiK(8(Px} zJyVP80O2cZDhKsuZpJrcvAY=&4YOhWuCzh+jHKyEsucO;9F)r!Iu!kg*D%R)R6GG1 zlCmo0Ub`z$3BxK*&Kw%B`=7$f{ViRjw88QO9_VW%W*dJeGQ0T`pV43Q2jJKsBUmXC zu)!mk>UPAW)GQ-$*Q<`9BWIyQV_U+|%T$g97Kyxr3MA0WtUesWts?vU_X_LI7dYXZ zS?eap{%%#|-GxG#&Ogm2Eeg8MJG*RvQs@*zF38$j0bzRsD5nFth!I3EUs#E`<@4EN zt>qtDLanGdr9%|W`#w>k`WCWFOy9I4?pcL$xF<#Et;fCclfhp^=oe{up>R5ffClUl zQL+E%7cl%V!4cFiWq?h>A%;H_xjKQUoAm@IN9I&SGEX?ouy9yCR=yvr5I-fIB@q^m zM|HN1Lsl8aj3l8B0@;V8V3o+3qX-lh!OGA}=-0?supt2tv-s6cVkSPYi-R_>n=?B<^9i_C!;lhnc0^9_FXzt8 zuM_dfH7Crrng1Z*l!YB10~9ZBa<0pRRZ5yKCm94W>&{!nD3{W5Akutt*ydKfZ^g%0 zRCvn)-G6lhb#fvh!U{zWT|<26J;itBsM5$k)@m-4FWx;|S>VFMYxgVL(Mr>$secm6 z-tE?L>R!udDmClMV@mye6^kh*t3Ici0S6pYv{%j${&Y`^g6Xi|Xx}WwcA+2HkkE<& zy*E$<)QT9utvF`PM_ytFO?Vl~36t7r7+fR)EH?)rs` zhqzPi#ywV|j-w&V@l&IX(2QU+%Bp+e5a|TIU9=#XlY0*>Fvz5%6I0uaN2L14ilnQ8 z*sm7TiU8dGU&n?OL4HF}az+`Dh7s{O8^5r~FnLmJnESQ*5vU^{%qUs;(q}E+mZXAB zbc3%`gf`Bm(L!|1w_9~yrifrAr%f?J_C5Z95x?ZNcR`^YKUi3bMx91Q8DNw_JJHG3 zKj%JF=k^q=dy>bz5|KPSc#zj1AxG`ZTH;|v&hGmBh}J$|fgj+kTK8LjiMt=BGQ}$B zl9;i+JGzY2r)$3pzBWT`?S_7 zW5ZfLz4Pf-S&!60Zf6;8BOM-4zW=+u{osCav?%gLr&b0#Du`)53>z8&)lM3{h`Z?# z_2Cg^!!7FS1n&~c$YiiztDT9~kdCz+IV|Z{gLfW0M)eN7eDvIL$z_@_qnjz=({e86 zZg<^IB+ex2%v#R)b{9$Q0pq8+v(k6|S!8zY1|Ou9RDM>h_lEBw$}CRTyp6#aQ|apq zRj7~9DGJX$OycU}+D;pWGTak6E>BX`BlaMHX{!Y{ACW0%s`V#!qj86+Dj0r$*e=N) zRLg1uvKgDLU-J3Qa_D01IbfH>1uKY@E5k#Z>C1W03!$SRnxFg6`2qVWbBheaHU#0| zJG_}mGH1$Hn?YBGq3`#<3e3vaoSwzY{G(l(q6<6Z3YjsCjt3w9$%aj8@xD^6)iq;> zh8+#Dx=1x*Ph#}6y>G|b9!FxtnORJ7{O6u<5t~`NHGRn_d%M&N-C@vvOX8)ya|L1E*dgLpBpo zPra-g%nHWGUXFdJ^lo8dU=6-FF`n?OGh&AI6eY7ZSdaVhLzmu-# zX}>V$E1oHaucD(&c@?}SfL~c)1)2_qkeqCt$}ulAn#Ab2jEO~v;$1k2{W0P)$igqj zJXRXLR9X2^tMafSpH|N9U_^E4Jj76l zZ|~_VV$2{Zu{I4iMcKatzp4q^#VI{`Z{gdqD5~sX+LbG7`LISh7(b1(96t2%hu;e@ z9Y!(VOsxh?iTSi{rjHRb9-1OdCwtX9OHIIrY%mg9|7=pS_h6DS+k)<%K<#sC>+tn^!u&}v-J zd8YJ}1>?bXjffjS42z!sFc^j(GHdmU!7q^6Ad`+?5Km(^*M71~U$UNWv$44KwN)uk zWailTJSEt2zuR){y!sT`cKO{m)J4kK0fuB&qucatHE_7I{2r!&JLQVlKVoVv* zI2SED^?00Pbk2pv%mz+u+!_u73BYU*2}*K~62KPs7fAiMOjVfEKwhpGBOyg)nay0Y z7^&bcpCUzU1+@rP5oU_Tom;GFSF?wFADd~KD%%iJTi};ryf#<8dzD<>K%M=~iGQ8ls*MC|Y~%?1w&7_WTU4&s(LNIDWkeaT z^=FN;gl?D?Gvg`*q6S0jHM9L$%Va!wp+qx-BkdFnGI{FS69zY;%F9M6TtO&JrAI?7?@{l+Qt`71 z61|151*g!%kuuY{JXEtrT24sDh0AQ%Y|w&@PMs+7 z`EDK#?s@+AHY%zmQ|!40McgQ zxs-kjB9`PVI1g0`E_*MdKkFK&qKp6OW^gpMI&ZJX-l2)$To>{+zSmrj56aUX(A}t5 zZ!fNyvl_$2tLl-04W#C2k&S#KD^le5Qk`4y8^s)^tJpwZY=HF+Ft*`u!HrAU`9B~M zi#%Kbg5W&Hd-Kl`?Jdv|!c{Z|R~oj1l{)F?f}R)f!`e1eiQLH!n@zFsW!msT@>Pmq z?-_G@M_`S_j99^0T|ZkIw(%HE@J4)sl^^f&lqaf~e^5v}(ORz?C2U<3nR)x`EbiG>BaYO6q0QDgtF zTuuY z+$5x)&3ICjiwSUXL!rcBceL+We%ov}5YK`xRf51JAr~6`2XreMXy9Fwd0YaEI*po( zp>oW7gO&+;`>#P^Zs4s%2_+!~efk7+zYlht-)sGN8E&|}ctxpOGt3Tzm+GDwsZ&y0ZiuJ@3sY{XaXZV+9Z-PRz zcZ$zBIrnFEhM!WOM1~#Bqr88GbOUZ2-~9`e#u1~-!*Jx1ab+1R79dIPB;Ut+bW@)# z7t?5-fm+VLMw(L}Mo#MzfB72j(Z18ZLD`@%qshQqch}c-M|HE^AXuDJLI&kiv3wc& z;w}BY*t|KWv-C`H+8(NwerNg=2KZ@*E0u**g@{TUtll-NbCs4O^~LX-gbDNGVw)&NmdE>2gU=q5!OBXDpa zPFAnOn*7HEV5$l=EUHa;J7_5p`)tNZjSh3Ao@J(#n(u(9U`mCoLhkg6t`*NkV7qmx05IlSud4Ji-wvRX}B@hdA7jMVLoxLnA6HQ z9V4Mg7yp8b75oR_?V=fq?&+#9-z}`Kl&Vnq%_g$TdZeVTHzuI|cOYyZsH}h5nPL&( zTAD!!tZp@uSfo|RY&QykBy}cfU4<^Ts@5XrtEGuWz;ei>TrT(Db2aa!#%ZfWWQsjO8xkinR@0E*7X{$yHgt@u5Kriv1B?qR^48j! z*zbpsG)Hcnu}*{7QtL#p-N9VC`85yzjEj_etnM8oI%hN`J_TbQjN!QgW|x$Iv{$Kc@>&C6ov;T3S# zQli#sDs--2xV4X2pP~pen+39I-o$uJTY1E7<_5e50ABAW!p`XU>5fwK1zL2MtpSCW z#m7I^Aj}GkzLuel>l~W>N^0c^rAJ;GW-H>hb{J%>6aPlJTI5@35t-i#dnjq-w=3OK45$r%sHYk zX%nLJdb1p1pZR+8J&|DX(j7O}nM(94m)0E2GfjOb(E|46Zw|t;%m}6fz2b7r`0Sy& z>#n4{W(l7IYCETR1nU(@os0;w zN;_Xdw#>&q@eSDO#0Aa6d@FPks|TB_8Y*=aY7Cg9XjVV?@^u?y>A`fx`Qm8*5iL0a zSkuq49mk@iMZ$x9(p3)oz_@mo?BT`xc_8TwehmD|C1k(UV1 zS>o{OFUCeCBS%T$V&PA`Mzp;|a!M~l%fQN_@UWoLi)3s0vJyprs^Xk#J~&G*-lP|Y|hS&DzMz`W`$(1;ldd}2vW^}9dMr)&kUvK#?y z&nUH2f?mkw5{J;twHAX(H>x%z23~nKMw~(URSIj{5F+U*hUTWW)dA1#i1;)DNL4*j zKkVSp4Y8_(V5;JzxiU{fex@6Tf0nD2qpLUMu$lhQmcay5F8FK76Br3f~ED!7$RdbJ$pTF^-<$RmFH;x#oH zr|X8!25P>+L6mJi0G!4U>p?l}A*Jg3vHON=wctgK8>Zgn$mF%S#aeZH52lC(Wiu)! zmzAhD^f`Ok441sOgv)cF{%?;%x!1}rF~R8d3%Yw*w@KBRYfeQyg->(*w$u?;#-2TT z=DuqdHZ+9OoO_$upiLQ%P~v&d!SSwoip@f}hfoc=Jnbt>6ovZivazr(d9(TK;;Bp3 z?ZepKSpH%YsbePROVv~vL{+_AMjyxHx-dvP^NlvULrM~v-6-bAcX|Ow9(AC%(L1VD%zRxKUvB4UrX=8*2On^*x8k|T*3VbPvI=)Tp2^epCH}jk@VR; zipBQKkw!snhZ&EL%{ zr*)5?3U7{%>}#4^`eX zFx^sc<}VSt=^Y!ca6z{y%;|iD;n63sTMn7A;gORcTYcdP4M}f5U08<&*a%D*q2726exS-4fkECcgJvhWHo5YZ# zthN9VfW9@0<{G#)5hZ2|o;Knt#N#Q9Sy&O>N?^NzZXJBkY(7!coYM7$U5aaQ5x?{~ z^;9w`WDI9Z{&*-pm^*>+z`jd%tCM3&Wq^JMGc}3=c%hdr9^|!UuJuvk`|4|0%sC8R zNOCDFazWtxpbBsF-S3Oi``FfLasRA|=kX1}f?aceX4u}|k@oFVxK#unnAY1rqEYW2 zK`&~oIClKYuT9#AMLXH!;T|HcD3&V^KU(b8{h~&jtr94%>qT`-PvwLi)65h=yS4We z!!}xcNUXtsqR;e@gM8fp1~WC%*jH1TNi*&iiZ+pGYUGR$PNR}nE(f!#DIb)S5oMBg zNtC0S9Y3u&{6Tj^=T4vkKDUw4Fx{nJSHVpyO}|H}tUxjxQsHz9HhB|%TQhV$B7ezE zB>Mby7vL@R#gpsWO(Z+6dQf1q3wxR?`?{jYvV;EtOH6WN?1P)c(S@;_{EMP^WrH?$ z-l3^RY-)7;mg>D5^uKZn`D7z0kbg_x)qH=*{`<;>u-iWf=*(?x{=Ik+7}F^M%8wd2 z9VyOQHT#|lsbX<}(4vPUjRHpz9ysgdAMd;(wQ^3wgmcqa5rE3`J2TOicuN}$3?`lP zDdXi*|FFx4Mh7TEuU{Bg5y*MwAe9 zGAU=P_C_bd7UW=8S8_mFwShZ(c4T2I`hG}eQ8nlkQpV8hI!zIZF%;*gFTx3OMrwmf zfcru=0@6lqRyrTNQquY}w`a=iN>INgC}g@?(D)H_IY`-te3Mv}<@x=}c+2f)FViul zsfE_&hI2|q&Xo31xB#g1&npeJ>H4)7sUwvC`l@9*T&&!_Ws|R=fPfhOn^*1hE#Tou z&u?gG>ulpBZewCgqM~o*{7+4fL}lx5#W_TuDNLgX>>fhII6e@+g`nSY3HOtHk^tM# z-{>Xtab20l`Y=YB#F^%IvK;f>GpVdhfiAbX^V1*lnU|wc!0Q3`{o>8dp3|2+&7M!w z-PNBUfZ+aLL}v4di?dPiL0R5DBXG%{V1`W1wwiIdhD$fN?9($zQpScM3_^EWx4-s| z=W@>6Ad)ew0&uA3>>~rUetO%CI_nfkgQWv5NhU>hoXXtA1rhoSQAp;YjL4B&Dsp8- zVO2570(Ajn2xB5Y&B(Xe-s_AJx{ADdceNpSynUK?$v&~yM9yrh(J>|zVXB1@Wt92EsS>`^ z=~`}>qvO?{U`4B{4$opOqQlV-N$09W19?%hzrQ!qS%wx~>!Q#qkRuzqN*PU$C9^<3 z)rL_5bK@_T&S+4Srp`E6YeoTbdk~L#*EDq59Cc##-`pVJuqQ@Le{G7~Y3KV`?AtC- zx#*~Q@YdBpP3tGWhY`ki(3J}m>*{585W!%w$Vrmng@rigkx7Z&bauP6DRD@VQ1SNd ze{!v1Jh+8+Xi28gzENe4#ZBgo#7j4yxIKy#Ce(l63D=iF>D#l7dy9@X4wlex{B;_8 zCx8?36LJfMO3!z@{k#1ugr)&3BnsuMiPTF0(`1aA|pDtE3GChTdSkK{0t)MUo(G>2`Xs2I$YV* zB!3Eu({b%c3*IavduU2GEWLz3AGQZl6%s18pCYZ`4Q*Ro(5@dp>c> zT!JlUsB)mcTI)@r9N;g^upxWvh~!N0g}F1ey*$AlAadQb7A^CiS>}>(o;~2#n;&fq zhBeO#!t*VUVVUs+yqhR`IF$`y=K4g-SvJonU;4iKh$#HXHVpsN)>|p6MTud|yEH_` zMg=X%32#(qkbrIzNJmpFNHK3T1jm+My8-jAFL=eW*0)PX@%=3=Mb=>G^ci_cd>=PM z0IeEre*xJ~5*=`RVHiO`D15sqm&Mb^jl9KK==IDvaZTwRJW6PXC4ZlrTt~pqd#NaL zch6<5ho~FZ)Qt_&)klXom9=XL9aHL=1)}7KohwBn^B%ReeR_?zyBCQlQjNW!S4QId z$JSD1dp5h2I#UG)IM~-5sACo6ng)>@*f~cGkK(}+bmlma@7|;#2}EQtSaVU&Nc(EY#M*uTR@qLQW} zswnDbns$mYCLQ4xAF;e@=HPeZIfcBp%^`F3X8iR^V>jM4f_a<$@RG;GC2bD-P z6s(kWm#@I?2&KL>*cW`lGk=tEm2q`8zWvqlfzo5xQO6MAADH(?KLVhn)NtT@<;-0P zf`5xgfBKrWdIfz^>GGkRyWdk`bqTo*h~SFLWtPQ+wkb5u50Hmx`ksPad#DiZL8XwVeeWF%H@I3 z;t%-u5#bB-^MNt6Dy`RRcHGHrTBuQru_1gio)$lQzScUM02Auwn8@T1i&pav zM~Pn6?uI?`{9&VFIIL^FNNRq;i!?;DUAn#-J+aFfC`(2^9)zoXG>JHpiVl;OKK3R=k|{ipVTyX;mXT;fK~lP(8l<3c zOKgBpS5Y-b)+gm*Y)HF~=!x}7=L}UrhrtM^P=}gqVXD=b9L;d1G*YFbe=eL2RW<}I z{^(y`U79p&@s?%TB6Q`{UmZ{v=NlQ*>(&9Dpx9Y9;AQotE}f=Cs7P#i(wLs&XBQxY{nlJdA_D7 zlZjquMv^7b(2#33^~rs9cfmd_RE?~UxY)J@;+Va;-@5fPW8L|bZRYKu-T~W z8b4|oaGrDJdmeg|)rOZp;;$i#{MncxBDS{#TIKAJUeO=Un2}`zb9RrIS>g^u8x($p zP-vM9wvW8oPRQ{dA=2i>%v;dSkk*}ZB`F;)%y?{HbVKdn&dih+eB=x9mKZ^(WR5G2 zF?4y1vHY}yVLIpJsbGrw+zD0Gf)o^gA`-epuwvs zIp*{TRqTU**U>Z2fqaf@T>t?<;uET3t|N%x2ASy#?m5^Ca@w1YGCz0!0#))JHqmdNcbZRKjEgjprFQ zq^e^*8`d?-U`{wEy(>A5s*Oj~F&Ntjxi77INx2CvfO8sP)Oz%5Y99oYt?L>@o><>?nX&4PKHuiH-ULC3WHCXuw7%!WAiHSn;s*9braq)^bu zv z8Q;k!RuQ&=YL$64(FC#aX#-5eHEilLN%HiQ09lMqV4NPVpiB7ymPeB{T1g$Xt!EZ% z9$t=BZXS-zwPQHZmIVhK-a?||H&NONoLgU)b3)p~^+Qm2*&)>YZD<#E__@OFaobPd zY^rX;a_#B*76I1{FSryjZVMLVY=>Q@}Dh2-A)Mu|$7_kUNu!Uigr{ZGOMV`kq{)9Fr= zbYsuPJTl?EHEL244$C#tfAjbqdYhlNVZ-j?fU}{F;=QYkpRYMBLoBk-?XL?S9YM+7 zXfzC5`VM8S`;IcENxR8q5f85&pnZwQpY0ynRg&fR`nQ^mxv8@o~P9-xV1Py#w z%?@LMF86^eCs>K&I4a)B6}kr#L{Sph);EF)XBLHW=IwKCQ2a_pNr5t7xWSq2iDm@y zgi-9ni)4PZWtq(?ZRFLHgUBli`y$M&{+bE=kwXF66$V^I0-_TEDnkI(f(A;1-_j;L zsDI#i=c^wyWQ^_N8yO_HKg8Q2JdR8|eS?MA&9v!kN=JzOK@o_pYnZ-7nCBz8kCYYA z2FsfpK~+cpFRgCP`n>XH5FntiZ}M{b|GP&Kw6(T2ce4I}+TM{$n==0pO)sLgrVIxY zLcD=MD*!V>`=Zs$fs&}VFo4prW7(9^JHC|K%#6Dx>k0@Z6M@6v`Hf)AwXRZ9NQJ>< zdid^jlDq%Yd^G@-!om zCTPT@VOMAMI!#Zn5H?kWCS#bQf2RtN2?*8l3C0})Wc3NdptRhlJNJuC>%f5cU@{g& z(xvm2X$RGA$WUHoa8(r23yITdw)mGkWp80siN?@EU)>PPn)Xyxy_RWDkmuupk91qdIuQ4=$gV}!7%6qg;4?TIL*w_;=$(6x1wM$>=kGGl8aTX zTd(pW%5FoxbEQ0ehR?<}NOMUE_l9f6Whm8OSwYm+qr^faB@RnPdG~O91VN-CzO+;( zd1?K?-P3Mu^Ayb~r3z*^9<#wbaqxcWHn^CKA{LZ62K2~7b3t?{j+tryM@^$TamF}r zN8Mf?7D7{VS=Pjlky)EY+?Zipar8+R_YbUhtkP)hUX|#bmnP?2D4}{!SX54M?DrY4 zgb(_eA2!W?&>?IeK}TJB&p323DO`OlIqBMMpiV6iX1L*#kT|YsTd+@Nn}aBA#>e-l z<7$Hg^#2uAZEmL8JHBmT>{_i&MtuSrmZ1|7r3CX{q?0@`L(6=%DXL4VtboTFt zk+7vksY160CeObfRsQFl6 zs)7Yx*V;*fEH)Hd2lx@LuMCFPUOQ9MNc0cO2>P~+pqaW#H=zQpvZn}m!LjVn3m z-Wacaur*X~;ZQX~BZ8(F_)-)eTTX=r_cZ}4zi_0r&jlaRI15_-8r+M8>`$H$0%V8>7CIr@hirCe3k6agtUN=G# z#%^wQAkrLFW$Ulj@ep~dHD?m4+;6EWadz^fX9d)4RbxhTQRIUz^*YGCbmZ7U5&2q| zS2sN{%bAlUr5*!sD=*z=1@}js!&`9>-tbxWUdr^PX&*{rNOr_yKg2N?RVD#x7oHfU zc^2SRE7yJXQ7*<=2*3k%v<<6DYXkOw2we>bl^iT3u&hD0+~}l~6P-csV5v9FU!kTx z%d*f|**@y^RMhD3`YTaw3<;w+_2D**Q`pfDM?sZQ@VqbTR(7i7dkOp7E9OyFc$UeM zjdhQ)L`ya5YZpA_eL*hcE_rsVGcR>C#~u_a9JlE`$hS|}Khqp3@`;pV zQJVQtHcwsa43W0!FL3|MG-j^tJtRs`Fx}9-ZA8B}W`4_-fKjaFD%ar%*$9r#vh;@K zX!wi_{!{D#DAxconeV?yTcjfJp$dH`hy;-TKds|GmA(pLQ)P4z8!92(y zbCG<_&8C4K;PtUhkxZh~+I(wZNvwhQ z8#Oku{2?;IP0+&qGd?pTKaHb<=OGf0uzi!Kzq8tz3(#R&;Qz8OXt&oZR7srh3JDtC!{?<;^h`c?JSja2~ofPBGlvqTcVc+5aCF)Ur|ar%ZkYZ3BrI9}d!4snvxwfXwJvDa_wglOLh~Jw7GM@Mlv&Y(ZynLK9bL*vQnIAHLh6 z`vfr(LZ=_=`rJA|BUYFH1{f(dOazLi!AX^blq}H=6M^Gx@LdjpqwT5^ij>GkI9V%9rMr5T7lU{Qy#HZ;0C5Xe6~ayKEzY>obRwV zDNJS=UIl~Jd&S>hW=vYo4V2o1#D*MMMA~dQu0*Z8X76;F%674T8RX^*p5k(+LklkE zN$TZ<{dkVc@@hpS@x?_PEKYQ5x)p0kv5OTCKzwp$@vwFneMm;*RAf~kGIjf2sP{Wk z_PGo^1DzJC9QmS5`Kj1{Zn-@aCrnPaaDZFHNS%*Ke(fw!XOPwM?Xh%$*R>oy?j||f z!90^bJfkfuxZ|;jqnkI%T+wbwGLVTo;z>{B2;Z{Bm8%VdA8!9k9Ji_eMbY$)Vf^1p zPydTJ?msZ=-*d#mf9Okp$8q4$nrp&{@-|^?JxvtlZpq;iD5#1(K&1#g(#^y)n^Oy! zt7PvezCqtn9Kt7%Z^Dg}Ix$UR%yo_9p+nbI#@*!V%Y)|^`EM|;=^W5ZbOqM7naP>% z@$`+G)(w{>>h?Ys*v-4F`w1dJQ###Cer#@ZM%KC-tXrxT7wmdCQR=>HZE~}gs8vhI z3!0a)%1$^X7N^K!5<%7Yw_H6pc@7pcqFTCU%tOY6es&!1V^c9(7)72P?XiRDDX!lz z=-}2`1BJu}R%t!)>#!D1ru6rSYt607v0B)c^`QPn$7OZU~!0FTz5fUV=lv z%m_661D#{^mi%2o`O#5JH4#;I%6!QPOP=88(=T<3DT}=;@cQsL`9@JE;ShV2Jr?dz$x3ST% zSt6-tY8Q1{Q6_V)XzY+ZhroaI zt$pibe79myKhZ;saSIWHB_UnM23gG)ikg`NNCs#F2DG3T%+t1(3}8Ui%O$8yp2;t| z%}mk?;-{QmHwYF_)FlfBRO|>|Yqq$PKc-w=rtx2@yLCT-^^n@xopR>+l0zLw0QdOU z#5S!P>-DS_5Pd4JshUwoCF`)6fd-3wN%~UYo=Lu&%>v?C?>%+KKPx6n4mlnL?K6a< zTwdfatrS5Z*bGv~FD2E%9EOMb+DwkShXFUChCef)TcQL{$sX$+rLu|@> zZXO)~GsX4C#eiZzgFAuRwMc#~R)7&vFf}aGr23C8>rzAA0F~890aAbGR%%Q#D%0Zj zm_f*ccJlt28|MfH6k<%%k>x4 z4WCe#a`JAMAva{9=vy0?PBBPZ+_g2GCzbduC0kfU@t&IjciFN~O+RH&6~4J+^BAb; zcxavE1t+Rg)j^k{Wio}+b4JuH+znPx{Dewpe!|8rn(C6}?TiLe7Gw)@djn~?kr%+p zah(y`s`lK>qO%x8cm77qSyrO3|HV?^Vtf-2E(*&g!;Zd3S36QAGjJtZee8Z5sxYT` z3yZE^Oa5n=-7AnBylYAL7OwxkyZOLP^j3}}8GU(@@qiN4gOE3~DrJD7$SK>iy$Z6J zS^;0=bCvXVZ3vI!9QBFZw7cX--h{U6y8NsEgmUy$)A=m`HP`Q|l>URf4BTQNWZI?h z2%S?g8>@f^;WP@b?Zt1GDQ;@ML&}ge;1gDE-hw3}MxSvKARd&;+z*QtW*$UT*YGR& z?Y>>2C>zJ=cjFvP&D<3LfBL9Bd;dMVn;`1I6q8hcPbh^*|5Yf3G}n$O zAq!a#0)OTT(;M+OSDPJF@~mjbYbh}N4t%C?ATz=!2O`Q(cQ~_(rCR>`l*>A!dFIL> zDO1%~G|=u2|7qrgemG1f7co6nl(QpdrcGAG-y-RLLu(+LQebHo;AvJc4Jpvf>#)q5 z=*Koxa-~>i-?J%8)H!IkGd}r+M=h^7TZJc}*lcDrGc6y;l6;OpcS^r!7l7`!ivlUp zHs{H5V60PI4BBfAA#`Ud%3mb0mAxbtqExp1`iEwC|05M-3K!Ifj;Z#v{Dx7!?^KZS zfAk@Swl*f_ru6@o0Sf-x_kT7;;;p}t6mj?qrjYg^MxlVp3{BV?;Q*CDCnOEBgs?OY z$UNezX}Qp*b=~^1sf1u0BXS7C2Z%Sp{*fXn82c2CRn04QtM9-bI; z^5=mbta*@EIDsAgPT7g|qGlf(>`AeL_+5s6gI1|=tg%?5LFG_vzYuuTAMp&smi+vp zWgTG`a<}~4~vU6wu z9u>-8DYc}~WP4PHU9lS0kp0GpM}Tkxa130n0n(ro9&_n4KD)sf_8opvs|yCy@hj>@ zCZzJFfsQ}pEdsr<&m;LF6M(zqk#hJdeZO4PTUpLb7fn$SW|z0fMIqF9cBmC45oX~8 zAe&!m4fB7!@Pg(71Y(Cuoi`C-6_rZ|)@9T%X6dRS`oi+P@fX}kE;^5-QW4@bw5mR% z56fXuY60|L$2^)m)Lw-{fbLCskst#_yb(2pUJMEI{tLTWYl<0t?JLjf?=pAsE)H;(>U#m}JoM^C> zKnU8mkWEdF$dv;L8f!iS3{O`N(>im&o8`d@h;f3*9?B!4iw|o1YxseMNb4pVd865P7U5#@Mb_NWEzcrLJkbpf!Jg9(da0bpcccGO`i_IL50Tnl&R2pS*O zASuXr?TL5NE9EcGE8KrvUB>ULtARQ=G4c(60^g0i|9KwapI7%^Yk7%ESB@yksNC!C z9#ERd=!%*e{D_uuYgIof)_@`jX=9n8R*}W!?bB`gUE($;O!_IZ?|I{L{270FJw`ip zJQ)WHypg7g+f20{Wx8Iq+dgIce!b%KC^s0UDAfG*!0Ys_twz|WI!SqJTedy>l=ZgE zY1THKzC0FgUatShI(W9HfGiLBS@yF_rwX0w;9?FAY&;Q4N@Z2JBt$aVpt4QJ#wy7M z;3*YIwd#?tLW4Dw!d*o)dfp&kWuqkV#Afk5v+sBq03FFRYadkVs#K5)&1TU^OSYxV zK+O`VP^*-(5l4*-h6pXiC=oY1455xyG{hG3_|U$E(n z7j7|XME!Oss7M|hrL(@;yjGz-Aj)8*WE7i!r~@N0RU<0Q#oR7f-c-EfaM*Kdu#5|< zf`AxwwJKx!umf-P^MhBVHUjOG-IlY-SGrf~@OsRlX>`&zZx4h{Vb(zxY)!wAPiTiR z(sn%`cRwH!|w4D1**HKet@9)$CK7K!r z92RZMemvOouHR&Q%QPHhU~?ci%m&lW-hS$S)s#o-*4TkP9X(``O{SkC!b?gE_UWS3 z>o{`Vspm%hq*q_dLE)Elc=B}yoGQ*M>$M%Uj>VEvyCF;?GA-dM_Uk6i<{qq`;6wVu z=kj9K8lRx9%{CrCyvO%7-XT~6Tl8IV=LtLtBnXs+GKIB`m%9lPhx@_a3LBtp;1F0@pmX>B(!fOEP4-ZGbkd4Ma$49o}Wl$ z5d>oIIJEl*?HT_G^oiG8_VfKVqoYw)aILWT`5a0B+2>myHUU7U&y%N}2q4^jC}|?w zZ3xgEY{(0sgpw4{OujA%U{jQ@q`8S0XjWjTB)ZvPQp(oby(wqJFu(Oe^_rF;7WsoR zg5nx}*d|T9THNm;WGw||`T;71<@))bCc^%KXc%U&@?PK5V4dHn#`(WNG%0-tQ)5S` ze-17EXK2fm*Oe4tK;^x&J!P33WAr?sg~R@VWCTWp>W6Cd%u{{F+U^>^NqJxE5t0+k z!$&~HkuD(5BLq9O3g7L!zQwDv4YY&WbQkm62wefcfKV`p%Ro^?kPOs=8`FLpaU=th zastcmuT6gTAJP$H!Yh7YE|6de2q!N))csHxHu4=M5 zrwv4wDkVmjU&&PIVJcyIk4wLUOy~x1Rt~1G*7EQWA94xu?rvi%F(~S!(XP7k!1Hm~!a0~7b z+#Q0uySuwvf*#!6-90!2cXxLQ?hu^tpR`Q(*VC(~=bsDKx#047YfJ6gwIxCCDhDb- z|0}?PxEymQL)(7?*s273dsLy1gE>Wa(E>}eO5qCHjp0&d*QjX5fTYq!T(tZs)*k}V zbao%SP3)Pjjem(6?;;5J5sq?tE0kj4qOzr|W#FW4@v^kP{G}Mx+g5~z`@AB-tpOaU zbvy9AUhkyzz8IRsd0-24B`Tao1Qwm>@kF7|vNI!ncfihuEqAmtfvv#bV}1e8WuHK>Il|ecK4TpQ_B2 zu5co@SRVLk5&KMeW=SV_UWVnwtWb2zHe6vzd6=azgyzZ<`=)w?hI3gYj(86y(0}>^ zec4YRXLew+S~0}WMiF^0uR=~?axs33!9z8Bg;6oKYJ-}ISYAL||1ewdKA~73k~*bc z$&~C$_rtTTJlvjqfaIH|0>cz$jOAvjq{y{Ajj7Bq^4`gTn<08v#qStd=0cm{Uo$S3 zEc+cD>s2ze*wi@*@~fk_>7F+GOq`cR`zN)RGXy~PazM?yZdMd--)+~ybX+HyVM?@W zfZY;mm5cPSRB8eo5HC(QKV|aMiexxlfy{4A&-6|T`-*$S%0YUA4AY`y{jP2?+nn*+ zP_MaH7|bdzlEUK=BMe$9g(&95I@vDtA+ob=%#WJJP|YK5M?BGq#pxF!Qf`)PQrr=V z%ZG}KG9zL#lKzP{dIe;7)CMg)RZFS!^+snh=yaki>2;OVW9i>7WJ^4Jl3Y!Vj2GGK z+^P)+C`|?^5(UY>U+f9>7vKf)oppVFhyI_@=kS!{EEp7hWDN0L!VEXubwq$Xk{MQ?Vy=qUcxIU4nC>15 zWOStqfvBk?L6=Mkp5EU)p=x82P??7@;}BxS{SAN6T|iyJZtNaTGy&*@4dpFOk+Huo zG!8NX8FfUcyI~=q?cyUmypT!y zU(z;HrCY*_nH%W{RI5K`jd}zy74op}z*2izO@TP$sH1W2KX`W*IkFW#nH=(Y z7l$0xZ`k(JPX2Pd)pG`q=(3FdtvVOQUfR0fI!5@9cm2~rcxr-0orB&q0mLCo{Fm>l zY-(qs;$&#&Z1|Un=wDx$Ow`WU-UM{({I4x>m5S~ka+%LqdzF3-S?UR0;bQ|`FFZs5 zdZiIYJp7;$>9u9M?r8k?wKF?OpIgf7yf3V{*>8%2JaYkv^H`<{=jY>@-jl8M?gxi8 zH3DFtiT8#Of#%7&YUOjP19ddzWfwGVs>AVQod%yH*_FVe31k-u^f^P7lJtiYNa9y|7qlkARj(x_8C| zi^-OLNM;ah{?{NA7ox%KIhy1$mVUI6_3E}78W9~e_VD($161~CdVw}m5G_ai3KPp_ z?Y(cSUp0RhWeZ#pQNEWFbgW0T|FmtXEviFEeM` zjgl<-NV)pvm#n=-H#SuwFw#AjdTnpK`i;4ym1&_C*jrSDr>x7p(erCu+=pm7)NFCv z+9v4Qc%Xv~HmNeowd>&)7DjdaR~stZ55J_emx34E%ULH4F8w0&02!817SxET-kFa=w#Vcokq7?aa9va0}$SA{Dt&bWH&Hb4Rod`)4G`-wXE4D&tLzk`u+o{ z>S(qo4Ny~l0^+3g|DPZQilP4&YhPR~Z9t{nUy;_R>TQoE{_)+GfPaWD{iBhE1hE1{ zX5XGiQ_&!=5v-&MfmA+GKu`le!{p$h?x`Jq565xW8+27-Xt>lHXm?T7{9Ky2?)D=w z_s03=8Hk4ZTF>(`)kO%(0Npasd`GU+hxvrmz&zE?!ME6o^7kJfGheQFw>~iza>QZ>1=Y2fo7nUvn3`O7DJtC7`78#CvY02dRM^$f`#MBP3)(zPEkh`fl3J zeYT4&hRy8y+fFZ4B0M$u;L|7bmfHaolh^_G9D0wUbJK}KsWrNrz6R3Cwny+oY`J+)+1M?=jFj2R>CfysIJRYhKFTlQ51L)YEZOo*dEP)52vQ0^SkbwLYtodqQW2VXe`JAHPwpJF$vq_^@& zDsxaC&=U>jy?JwP76wA(3=dVORYYaf5T@vy#|@tT^cY|%xQ?5Q#4 zjP+@5#v7 zw2UQ8Fw`^=eJPX@7y?j+5eQY8ohSrBu zT8|h+_dIdE&oJhR3nI)jK8rGJj5N6UoAFDgCCPjRdnqt=Vp4==zB)Q>!ieo7i^>sZ zg5OhuNGzFwK9td0&7Hc`&5LeUMWy079S>|{rFZv>w%s1?6ygap5a~~P7xF%?%iY7{ zY_p%1qrj;~{boDu9rkNjf4DPUhw{o5-UDA;U|Yl;*;Y%uZPp8M32pu5$okln?jVP= z748Ma+;79LUf1u%vB1>PIpR)DI(fhrcaH2OZIh6ic$@4xu{h}kyZZxf2|;9j=#WRi z%=^D6B5d?58-hT2vK&;Q3;e%;`tRxS{Et+KZw~XhaX2JEO;Av1Ex!`i*r;4gh>08n zF_t3s(YOtNwEN<$t)Be3&s_=aOMV#gwlL1+XKMfiF*wIc7LW5mw)15c52#LW29d_w zdYIHeSAnzTp11DB&M}OwroQgFf*Aklro9T;l{$3@bJfy&t>L5tIWphIk00hJ!Ebes zn?yChga^MMd*OHyN|P6q0FIrCGzF2;KHmU7tofv@6|U87H8cgI{ZtG}63q!lI5JNa z@OEHG+G{R4iFJ#xzPx(x<@^W~IdwQ=%&MaT)C}S2Nxn9^rM~?XQ%n; zgDye1oq>1fX8e8py=oMan4|ow>YB{__o~2pV-NM}%mST~1|Xb4kG(S38)8|%(~@a0wb5HfP8f0NLF;$)n-mqwjYNaB*^GP3+I}7@I-ESkYW%(ek2hw&4#Rs) z_KHS1>+zY|o83{UsAWE$z=-vv4jgdz`}B;p;mH?C4Oh_>`W78)=PR_5#1yU581~{) zZzq?nIf=CBA|5WedXlK6qpazMROT#q^i(px^b0CRDHBhUPB}cgk0$Ktln?kezJ$k9 zCM+^@%_(BJerf%kIHVxkU|zg_6Sqi}hq$V*qK3#H7RCvH6;FJLogd@FJ%O=IuXp$* zf)q@Go6Qyj+*e{a7`X4MWfU|y5=BGXL***w6E5R2B}ie>{c=yj`F*S$y$hVVX(G!S zFpX@<)MhkIGQVa+dZmon54xgwuC2lsBT^$k9>GL5so%DVF8FER{-wZIiIm1m2Nn2* zppTsQzxlwGEzRu=U0j_^m0dtT&i`EJXDPPZ{rS509x>Jo_Wbr>5OsG+NQ(p|$l_v) zz-HjdY+4;SHUamXn`sl{l|`@0=@LQ`=ssYC!A|ZSh*YfTJcph4nJUOVFZW4xKNuK$XfqXnY{}-@Uo5tBs+H>Hk*!|2?Yx zwdhyQ4gL;`S%r=Qg_4qAO_Hyq04|VUmaZ@dvsJv72e_D=-=Krze+gkF#wC0O|4p@* z)ufbXOJv2KwX))Uu+CzBaUPSi)%ihVzzdb>j%?aG57`kIhu=Ad4>E``j~gPq=6FRD+@`7LqGDGgO<2RGwtJ zRfjhutQr-O$9Wa2>7`ZkAjt{Bi$sA#Pv1($5Vz5RXxMcQt5iDt$=`|I(uYWA21lkD z(kp>3^SwBkMKSBHuCk)UeGZ*=>U8nhxAE%EZ=6Gnwd5EN`!I^^?aY{ij@iV=R$D1? z4CtEaqs=z-BK~n%{ZKL#4l}*vGEA9v;ERp-km`Ui-HV0(Q#xS7n;ZQWu$1uadoYd; zF-Be`x+qceJ+@f8L5)@|B0GL)`H*fMwN8BVh2_HrJ90A)bB2rDaYR1AbOg;>>NpfH z@aQa!H)|MfYsrJiN_A*yr^!VxNb4uI7sdk={v7}Alun!xUfbtLSEVp@wl1;&j?9)Q z>eZimaWJ!$8HC;iwvr=i(KV6POA=n$EAIv0BcFQ|M5;#lw(bsFSI@T6OFX%BHBtzn>8MJl2M;P)yw^l&JuL|eX`ewlL%!DDLy?69}%n0?Q+_NUF3+B-E- zZ@0rX8-3J?J3@>J$%94n=y!Opp)1UOI>#w4y)e34niD5wqryJ0V3Tl8{(4L78=1y$ zjhvYW)~MudkO`r3d+v_|znlfZj(Rs6V$G^oGA#~)tGM)Czx#Vm-13k@@;PaeY|#T# z^7&JEn6C`S;mR3rFh2@E5RcU?uFw&p13RCL^e&P_b_#pa5EaMj$Z=fBdunc!*rY8E zfx{7@w2N)h8lCR7BR{VooF2cxA{<@TU2(nz7r0hPrKaAnu7VD-hL)pJ=){zN^`qR} z*R#bcdBx{cru=Es;+lF(f8o0OiHF*}pcct_v&Om6Q7$L3UNIqr%Q=h7Tz=HD z*>SK|iBSDIw=*Uk5xMT3>K5T2?e`x9;+<-ld4i(uA1N~De}h0Zdl%Dx!}=vDj!AuB zLgzbH9-4WsoQmS9Fc8#vf}p1QqNteWYZl4Yn2?y(ux;M@u_u^tTRe=TF1Hkc+`-<7 ztA?z`eu@F?z793l&j_RFqp1ou1&Ea|-JI=|MW zH|n#d@VYtJ=ln~$bh0%y`5#MLy3TlP=zLONGC8%^ zxh=KOl;Ft*;EE7_;!#pJN^7OqDqEouJd>@JS9#FUwQEh?@MtswQUVn2 zilPf{m=YTGTotjHk<2I)Yr)4PkY_x$EBnj zA#rN^93?Fs#RKU!w066(gFpLm&OHu?XX*m!&owv0?NHPw6Qp>fy%A9sxsJa-m1V38 z?B_My&g^C$OQ5#-W=jON7sFZ?;H#?&m`-_4Ep-4d+8%;Yi8=B`=^u(O-oKsO_8jf) z4==iWVjt*iXxGS|_ZS1_C(>Bkl6VRAkQ#EgVbJA{UfG~(^LnnepB?;4IJBWGL3U%5 zHv6Ib>05TY4J}8Eef`xHRp1aiGBP&1oU&MX=S8^U0YKR~$H()S;Ul`HIC9!~##_m&D(5n3LHeTtkdkh`x@ zUARmHxkse{voteM>M62n%HT26O#1FEU^N8=(cESti+z8%HuIoP2Drc)qspw{S@fHh zc|11}5zFHp`JWV0d$^@_}00X zD`nTm-GmM~wA7>IqwXWQP@+JB1&iuTQDOd=IVy%SMim)`E?+|ESIpEblD2p&Fs1W&2M&95iAjdPBKo<^@? zS3mIPX(o$p3b=F>zx4YkicYv}QLa zh@Lso=n9~-R9XdUw^GBUVEEDzsV31hh6|D;ZFwwnYP*wqb36w0!(0jRqLUFkg7L#M z(Mu4q5ve9mad{82@bI^9ee-#P-i9LZD$QLLnGnZE^j}ExsxhgwA=8&P;~s~?or+?6 zlJ>Xy_VKeZ+?cEfzt$C0b_;9#ZC2~}CoU_BIZvuvWaq3AUvqhx^rPctk$VGsZdrH8 zlR8NN+dy1Mg@&ck!Vp^n6v3M|)#qT66Y@e(&(w*2%&Xv-2gUu?a};yvn2n2fo=nff z-==|e)!P+%9)(@AY(hl-y%E@RYTUNxp_mpKs{C6Thy{-vlbb*$gCM2x_6GG4u& zCNFSMB&Q`&v?DPLD*G3*c*~Lk)4p1h=xdpt!S3aQ!|mYyr#g+P9FKNp zpJ|tSpG6HK1np6#NvCxoUD7!1*A0G19?_Ni_%-feg&JP&;iUHspm{{p$ykrKt}a|HGza+wUD%qutM_a zy_k1jf&|}@HVT@=MOVHmuNziVeAL_zI6Z{)VqQ7t4;9i!-^J7ci|Ee08*}q*vZD=S zcNw}rt*&}Fm097U=6C2Cl+xzM2yaW5j?*)4==Xu3o+-86)r7b2>K+S7O4e0p4^o4a z*yL5wyOnR)HGG^grr zc8AbO;5;r%dX(6Iz^^ly7Ysqp%eqL=*keMl>*n;&!>wZe94`Hfr<&G7DV?1U*%V~? zwa8WOBlMz^h*c|-aTLC^%&z|9sLqtQu(&wZBFRZdvwp!Y@VQd4*;+}pB}-i?S65>i zS2!+#933tM0eFp()+HJT6r7Et|J77BHF0@ws-ez#Gs*M*OLpc|f@jsW4(p@+?6pZ1 zRmD9mMXEd-ZJwmenA&$pXl8%%P%M)^_Z1or;^F{^RCYCq#-2pI1S#$BQ-ZK8Wf~P8Kcuo6_kFdL!A1RvwU4e+9qhGZj*ATQ z`vyAKi6>Mw&R1b;-EGP#PZerl)XLV?SlZrJ49_{6#O9LMehDCHU+la+4YBuU>(d)|T(;H9S{!_`?tHlv<$#UXRFh&k=S=vB8=)q&RN zGUv!|oKap_m;6d%ErC7RN&ufeZhPv@CwHbOG(Ztjb7tO2*S+oBppq*~Re6Lm=Y+!# ztW&%30=1GN?p<-{#p>x_A@q~mq`o{uEkyJ3JMvMZ|V6mFD`aLGkP-;+;APFTKKv>bq4j+V8Z~1SsNVWjtiXzGeMlsOO;` z5oj`6*7#Qr8AHq)$Vk#|>Zlj-@4scm=bcH57$VQkh`uLtQ-xNYgmACUylj5R6B(~M zij`bBQLj>3nV0+&%9i%5OM7#oH7d!D*SqX$TN!8yw7$f|aXr?pq7xnRjtSaWz*io0 z2UrIO30szSd3lbVo!C6LDS6(#eXbw8gS=3i?&pJfm}}B5*zcH3RDto*2Y8iig<1C( z?qLB05FfS$>n^vs)w2{*x%5xp3e~4m?U~o}Kckm^d%q9i^s~5OTu)R}h+9w24`&m$ zi_HBZhiEz=l(BR3?zHYd<*;*J&dT*N$_h5hYU=N(Woa|}jB`HdfRU4s34xK#KQ(=+ z!F^+q(4Jb1knU7~RbpXN@8UA&l~v6fAGu!_EYSURLc?yFI}Sg4NLFj36QZ*_g-ny1 zV5Giau&d{Z+?-e2U>$jn)`xHUnc_pCr+A5HH}Z{N3Ora0#0)DhBrXpm_meY{#cu)s zPQJS%B&oE`@!reSCp0$HoN4!C@@g@ zvJF)RrIHHjb1M27JOtEpzHLKcY}4|5KyS*inMBjZcz@PP_T0DKscC24lbt|;Zo;2C z7j}s*?dVzpCKu!D&E`3+&XnKYZ*LgDZawt6!Jz5(Z2*R;J9kK1d(l&-W13r=DAk78 z*|&w}nAp%`NmVHOOh$PI#^~&Q_!teD7ZcS57*ALDlt*pRe~f8Vl6-cc@MqQmE%WPa z+3^V#U#vG#0R`)>s#FuCbv4x1d~$fWQ|>3(?DdN2%Ix8svQKLP9HQNf$^vFhT4&fW zv@6&VU~Ad)6tKn}(ddNBoDt4|0l}6p>E!yY?Y7lxfTCw>dR&St6YC~Hq&;^2UQeJh zogwCnK)yK$$nJc!s4 zCRlc^op34T*7dDjf2=C+46eC**rSa-v-6FSl~Tw#j92LV$%jy_IBy)4q?67Qn+n}S z|5(r(JnP6$N3pYaN%_svZ#9Z}dA;2jV|pU}9?1_biJ3l&LF{ZrQNi{&#W5j%c31IA zK!vM|az@*QdCz(5Y%_|pYpsh@m)o=Ffx-;Y`rm5kRm%7l*{b1v9va=G^K_MB50+6< zPrv*<_OU1?t3KqfuECy*SVh4Ep)zY-Jc4)h;Q8{U+MY5OH+qF)3t+n3^hCd0iw zt{vz5rk{(!eLrkxbmH#wNXbv($c3Vgrsx?q zjfey*sHW^=J57xgq-E)5K8A~lRM(b>{zs$X4Hbma-2_=C$Eel=bhX~1Vb5pJ?_RmGm&w=>BXiDSmZyr7ZdMFLf^oLgpla}49*rx7brV=G6R7tF zKiUIiap~bEBK07_8CG48Qim4BCqx!d)d#(++4huP4i=%%y_&ZtBdH* zusyfl*b zhk(}d^{-(pB!JJPDy3!e7HP~J<{Q5yx{G4BIQ)<(yjCr`>JfQ;jhrD@`Ly_fAWJYf zGt4QvT0VTB2@;z!Hc3KE(%?}I$pBoA-zRnI?-Gc!&c@$*AL+ox9BmL%D>U{jfbbrm z$%Sy2cB$+7qdVERC~Sdfrmso~{D^*!&|HvKT##PpDX`OXSP<6}0gJ#;dJ)pqP;mI$ z2T@1|63nY#RNEYs5MOb?Gb5pVSm3GT5Iq<$uawYh9YC1_(t#WE$_c&J!%C2U!l-E^ ziE4Wiq2dLjvl?8|1=1_6PQc-uAu?X$)h>9Bhxmz%OquwJm5haK>iT17n|_&dPMBkk zL0scN^CNvO#8a*{_VTW}U|5BrRim_=z#HK<@iL?VJ4}iF^CIzW52Ld1W1nBJ2X3GQ zW90b_QnM~S-o2Tt`aD3`XeBP%bDS}j!3LQ)j2NMe6&Poxq4KrQj-kP}N}|u*woA8u zLQmVGy>LHz&pW^Kr*oO-1gF#i4KPEHrC%k2SQ*3=F^N7ZTSgj18rBkzQ?y1MA}B`V zWY#fe4{B!ept}t`M%yrI;9o!+Ifodsf7AK)aYY@SMJ4vu(!|lD62xq><^E{QJ z5#&B{L|UtW18zLr318^QTX$|zauQymL?e|QE*NXmTFk56h1kLn&~#3{;c|whB{@4l z{s5_3n&I`M@MNBVjz`G`Qcv|!J5yt0whY(3x%JZJWyfHh6+eI>>D^k{;&_B{-*qJn zmRs2^NnMrhr8TzqP;6c@p7q4M2l;ZYhP#l4=E~Y=;TV`21#i$&bho4h%%?g@e#BVha*!y8sRoiO;;jX07t&8x`*4{N7`;rAD zk}T5Ly&rh<0rdj^lIl;x*dla5U4Z~-LL&5kpXycYtxfH|7}^-x8UNjMM|DH(ljz6a zxa{NK(^}%l24z_(+QJY>3a+Od zqm`{&X1#Ok&K||4!PT%SO97wFD&>WY{gVemGxe>>^Eu-~$o_5o+14NrK{@}$?xupH zH)QBGb&OJ-Z?{9uB0-feU&sxhQFdbJ^8t4C(5r|-matt{!hPswZ<7wz(+Mm~To zPox*r&r8pon5$BsAF;v>l)FUIcwS@bWDlE5|8W=jbw%FS8{t?C)RnS3BMCMgHC=&2oAaK%y58BHX-l%N3T*=yldBV2ftR4 z1-EDK)tmv$FGTM@_97y^Dr;Ifg&Xy2R>O`d%yGuQ-&TCLLM(2mR^t{I7VW9awODos zVQGp5QgM*20TB$&7JLoZ2l|lyUfzI$35SPoKd1UI`>N_?kCBdW_K*-O;nKkp?g|mW z0GBgMqVcy4n;duCJH@|R@@3$0r}x5XU9K73pQfGtRlp_1ZhF@*4Z5bsAm6?eLlf+L z@OtL^;1l{nmXrYLyc!l)?*Xx}rcZ;}F94 zhM@o^(Z$@|_M+KF)uQ7G=7M*iy_?Fx8SGID$pJjaj38&{R_3ce_Xvq)iUplgwm%+v ztweeaW0Y#;Ty@Dco8qR}&wr7MH#rf(Sc9Oe3xclT{}1T?Loxn$vRm;_vHlxci5*Vc z(zvm3K}&m;LPN7ki`L&NtjG^xxwi)L$R??ik|vtw}H zbf`ox3HO z_|Mw1cK;{pKjfQ`dWJ4eB~H~aeMw7!BIhVrpG^4gUdwMW)*(r?8&hAZtF_6Bzkukt zS=&&L3}y6c5tjsU9^Pa-zSp$+_V`{cPJ5xq@samm#CxiZIX$iDVr^^FS=(s}BnN5@ zR@L0I;xB~jH)@27YL3#Bj>?~VjXfUC-hitk4hM#TJCoKk4_ADBQT3|FT-a2~TO)IG;E{6@_Tbq3 z`3qztFL%B+7TgE8EK$x4OhBS4Mp1z>!knhppiPp4O;TKeqAEW!QcuHs&~u5k*yr)t0c-I;UQ0&(}_;L_DUO zWV@vty+G48w2ATGHq?hhEJ^^$mg>R|sowudbn>SF#dv?+DgyyI3M5cx{l5nC-@&`% zqznRY6Jm#@S5adwYksH(W7%>95m8~)w1K7ZDovTFD9AWS+G{PN{raMq<<)5rXR9a0 zLCpM<S@q^q*|$qu^1mT#L+x3xdrAWnBaE@pQdbjT zW)Vy@9@yRQRTkhQ=^pd!Qy|5hpUxc%nJ$R-j3BDJe?*_?-8#*&q;oq>MWm}v@mtaC zVYog{$KaMXVT?=i^6i9;Z8pWu2FWfj|byjL29WQ3kR$0NkoE%5^?vADG zwnTYZ6hxfYI;YFA)Eh_~Etm3PV;RJg>td8kXsH%Rt)6_de=)H;T4BN12rsu9i18gm zs^=xNW}4whG?W?~VnHhPyghP1F;LtdMftwkBMuQ<2>jIvpF(b0G1_CB91sMF0o^(v zj0IIq?zW1pS+Ww70Amw1g5TH%-k!03u1aoAvpc81xEe3Tj?=5F%VL>`{o9bcwMC6S zJi>fW3CmdCRU7?jgej3lV+a^H@hJM0hVkWd$?KJ0+(oh4VO+I>s(1|K*Aw4t-JWQU z3g$|v(edQQO?x(kK(1%~aBbcvko)KqgQ;$KJ|H069^-ad7vaeu+@DqK8o!9!)O}Y0 z&e_{J^sOubr7~dSrO0Q>RxuaN8%7^4^Iadt{i?A$?Jy#~nRFaA(+mwtjO#n?mu=nO zvL6|4yr&$vQ8}u5q9pBV9TDv^4LC3z#Sb{A=whfshYkpYUq?q^Q>Hhgf6+U-@IZJF zri77P=p=&tU-2^apA)+X^L>iiUxYG3@einHhL!VEzFv?%?*xn3NC@+KwQdy<>Pxs_ zEVYS@Ni_a6JNP<8`;AE2BVlVTlfQ>YP{6%7#M=zk9e!yImv9%_5gy6T2wb{FRNB2Z zK()G<`US3w&1dnRNH&c1!Z7o@rAnxDKiw|f?qR=%S%yc5M^4L^*MLWIf^9sL_kWtF z{Sh&E8N!1~3^1@;&>z)*guaNOi=ncm*Waq_UV+64e6qI+98K6aQs!Vw5aX-P%HRmyf04J0)8kJnBZNULFTzqjA+Dt}^Bkjukr#0OIux`yy!^#$XSR`7heStGmicAvU!KX%v4dkpvtBij$*R@@S{tmW2&Y4gEkMX9s#WNjq* z!mR$>{vYy^KS7y+vBwn$6qI2>lTPaY_%eT4tNe3VU?P(D1Rd#^=`0kSIl;Pzat> zvXD!x2gl4s!&z%dORjK4+=kO|%z6AJIWm)y?tCHQB+6_%|BJ`kuv4yNY*OVYw)mh_ zq#DFIn_7{61)jA)e_Z1|u_aXHPuQWB#z>KUJr&ibNv#-184cRz#nMvl>sd${$4^6W zKpENeA_0gwXsKk!@Vy3*WwWs-Wn1v1LuR8wc&_b$W;B=ezR73%p9cQ7pIWOFe(GA9 z9NQdn(QlLV)fHO|2dHH;*7zuwXqp5uqx6|nn{@qXcRnyhdoFJhT#jgB{;FL45~mNh zAFs3uyO+RXSY47Kch^MsWyOw57JtFF1l>~fYoHV>IUiG zl<7sI(@{)KewN4(OWs~3)Uo>;ctAZ*+Ow51hY7>Zg>N@b zoh!oju0e7`@c2hqqi3`(>}p2_T?%gcd950GeQ#g(Uf_Qk1xMc_$b$Zd=kE0-Chp>@ z_@K)uepS+HZr-dk>m{1^s!X1*QQDVA%oog^hv1=h+K`1e*DZ%65A75#J3n+}>wn^F z1?CebKL}qoAbipNpYio~+l0SiO!d?b4RrNl5U$QRnHw9HDeoiEM;@KzS#RMM90;Z{ zQEVvcSKJ!P>;870wJb-P%|hfEsVWtWFhX81WYu4hw)A@TumT6qy7!S&FS3S3 zHmSpUFGfTH27vS5F+$fA3jrMQ{Xw3c@Val-F_igO?Rm5K$LtN^5*#?!vGHu0>bAI2 z*^&KwddsLI&YRygKYNcJ_CU)Q>LPPc%8JL^PrUSw32vnk4mJ~|Mf==@7by>3Qb{#Sdb~=cMq8ai*fG0^moCIb zw2ji!ow;(*vA4v#C3gmw@zH9VHqN5kVL8J5;=Nb}Y#D33dZ6Q+msewFTg2Y6UEn4C zFna7bi9&%X@#rpaBf85kQEA4iiF{}EhRad5V?JW&a6!>1i_)I={K#5Vx8kx$I;zaK zt%Z;^^Z|IQk8VYP2vp7~nXM;`bp#T~M(YiNpOiiN^%N}#;npaMZ(N-o+JlS?UfA=@Ua}VbXN} z(VA!yap0Zk-CXL-B=p;-e1Tt4n9NZ~MNv{OxQcKu2L1fl6R&a1G?&&5i8wPeE+Rws zY+947+}Z5uYfDGwugt7%(#N$w(8k{H*Ql+`OS4MUd;=r8^{F3vDK99Q*C}gf)pbhV z701k4M9-lYEmR9vd@J{eY2N>7>EutM(~qqAFbtx-f!%0Tp^!Yl1^z;_55BO$1G_~I`Rg&^iz7rM=bN7=oY>_=EkUYKHE z@Sg=b`7vBeYRF$khnXwRo%WMc<4@POM?8L_p9g0AM}Ei?E?g2=wZ@IwXOg7 zB@@PK+rruw{8^-l*cf}YQgTmKq-RcV21{CrrY}ld#$>F$eD~;qjUZHOp^QrRCUZ$k zvR9O>Mgfb2)+$8Aelx+SLybDzAOj6in7Kyh0?T82;bCVgl-jeO$6JnX>WCwY6IHB@ z0(rGRef*_dNyYRq>Cf2x>?4`k{3Z88$yzbtmQrIk23HNiW_MX%$;roEO{~>Q8r#n@ z%rd`4@8)k!iz3;*<%PJ+P`BXRNZo0B5HD4tfUJ&Z12b%-Z5CScI8oIG?2I*Dk5g4$=rre7x-OnP| zShcy22AH)h=i@%*=^~Gu-fc`5y2XDHPFPfA<|4xxsSc|#$dNeimeneV%7I(YU*LBm zy5K=H!`0be0Q?4=8Y8sSAU@hz$g+hFG7_Lp1dD`)F-Z9I{UilIR0Z9`^@`y2!d|d_ zv^2qWf_RV|9M+1t1t*xZOP!60`w7=}Jnd;BNx#jdXLR&WBI7^cC=5NGDg%LI2s9h| z&xUUQ8#w;fm;YrVgbm#C?@j&=s|E=^&=o)jOA8W`$~3@*Q^$gp!4Sx%fMYhXoKD)H zUG$Gl_m}Q;BV6T2>Ni^pQi<>`KfP_5cjl}-J)IuG_>q4$n+CceP~+hrnNXEFEWw$5 z5U0(N?z{~0KTYiuv@j=i;0TKLsn^>8U28bfxhpi+V{AA?NTM&CF(o!Gz+>;*f66o^ zmRffw&B4Q{9>yP-Ry_PlhJ7%a68n<|QISa)M!#+*f**KS&6q@C#jpR!pns=H-;q6RxYfWr#hM64RW)MU6RHf-&&<=MylB7{CJf{}_9#usG9o zTQs;8?hptBcXxMpx8MYKCpZ-D4#C~sgS%^RcXtZ}aw^?D_v+baKfU%H54ZJ=|Ft0t zPyUot$Bws?EMBa$K$(1n9yC(~oW5ys(kKmdOa(7B{cnlNxVF3>XFe^fu}S!bx>M$L zmr`{ca@jS;7syC`%5Nx;w#;bTsG}IrRxJ;=k3a_!>!{N|((vBl-I_3&KJf0y>yalo zFG%j}hF3ISG3z|2RhA)rT@((F#jll%Z&31OUdy(_bvIKH%cV)~02)Jlj?T1|#A#a$ zVlU4_O>JTvVRSl{5j6EJOq?O#>nUUOveYSNnqd4g$p2w8m`wfXygwgc#%N_&rF1d` zXx&BO)zX0Z7*?S5YI=dT8@s(b(nbNC5ZSbEJx9o-p>aWh8mOn@QfLwDX=L>Ey|$4< z!N}=4#ub8V)*$^}ya%G3Bvq2gM+X-JjDPLb1s?+Pu`^~#W?2XIo}*TeGz{lw5rki1 zC)!H8q&Df~`dsm*NyN@6ZMf!HPI$;W{k@BX@NHFAaT#2#X92?TM!L{G zIK$tvj>Qi^R`TT@VO;^l0Do7X{(kpfPaa{v6UkgayJeC8ttcpi6o?XbuBMK*f0YFg z7XJRfKao(V{->J8ah>zSY8$5w9z{dLK%uL7yJDwQ!Yn7L!*W3;IXa`zr0#%x+F{_*4L6u%Dq6#d*z34nCe7|4$;> zw#wxyWC3-5Q#~*BlzGL|1WJp@u4; zG@o?rhq@xrI)qWZZ;ryEYb3 z9XC0-CBi369O8=G7%aF9L`E&I*#Qg&5!=sQD#ttL2@VO-Zqbt$9w)~OP$H5FDkht` z4^_E_lX_`=f^mKp9~kAjBau^ybIu?}DX0B9QRfASC`re36%o4pUu6T|Z{+*XW`6T~ zEJc2X{Njf^!tCaacA7oem2)LB*m~sfX71 zP1x<5a7w*!{bzVO_uwkC;DafQXUJ@%Aa$m=n*%H#xm6d-=92Xyb?>ld|7_-y9;$n; z7*E28(jk#&i0w0Gei9ye^UM`v*4e#7b2D58^LvJxuwu$zQ2#w*z0;{vZ2=W8Wl(4L z?=-G|0QUdi+x;1&^1HVKu^MdQsi9WkD+1hUf(;VDfA@B8SBnhv#apj)I~HWHC8Y;6h+a}KVvOucx)auY4LU{BPkA78AB4?>XI$f*i)ESt5E?};}m z{!R&Z=!cGo*^o23M(;Ru^7VBrwo0qN-EpMM6J3y>;#ITRv|Xm*I-nAdOpSvh7z4>c z6&7vg#H~;wUJn6fU4yQe_C}qeyO#a}n}^6~1+{8Jxr+TN)^J-HSMgAvs!;Fz>Ht62 zs%%HRW|(nvA~VH?nekjJ84rF}2_vS~#GrNV7X=_p;D=^iu?sWa)#w~8dE@vH4K z#wTF0p|yinZEyx9rJ5ZZi|^v0em8`4W5kd42#KZQVTaX?X6NF8I;8{{9FWyLZ6qqB&i@pnEtZ8c7Qesw%it$?h=YkM^X>pnkJ5q{cR>2$g*UOfM z^FqXq#0L4eQPL5~hr+G^?>sr=A`3*X6t`oTm|#HYOXrZR9fnpWj4$w->0Q<_c-D0z zT#PxE6aNfLwmIV~RN$ulD`dW4to<`!+W@;4h0r~eR5?r5ILjocA(IokMz|PGT0l6x z_=uv|;v3Nqv~tb9r+-8YUEkOCbc5i)3WCGG3&#F0aQLg6`^!b^H@(LQRf&I~I)Dzm z9MsG)u0ZxzSHcDz%V+hK~cy@hXa0tf3WdgXl}e|*$Z*q;%VY~2yPndRKeoD8$X!LwFfbN zW|FG3%#MclY4jxX#)PS(YzuIUrVg}F^Twkz)!0xaF)K#+2Bx)kKY?W2GT7i|G%lLN zVk6ZBaY76tj{2$63D(3ZU8H&+snPH*}GJT>WZ}^DI5O z{V5p6_Eo@faKc~a+rvOZfi=kt{h~?b1pkY4R@p@fiI*WG+F zJcL9=%Y7wclN7HC43o1Rtj&VhtNltZ1h7>mF(B9iSQr7O^F>vl`gdHznm+b{;Q0wD zA#-F?&jFrkWB*MWq?t-;pE1JieVIpZEZu?!`=b&>bP zeiemtQ^CB_5%$~n2ih%mf=0Qg_FDvjJW9u@RmZ5D44G=FwxhhEMl9!FnKLvK4X}p( zMnk_&QLvJ61}BjV`M(1O2~NoOBS znOifYKpj?cyh-}CBBpf!(M3C=nWYfMJ;xJEMGW26i%s`q-goOj^Y`eeGs2?tEI*+5 zHtp|up#9W)_o#Za*n=FTwIudp?c9x1`!US$B!Lol%Zac!hnoG& zz<(NJ6!pNgC z7IO`(&>T#QkUR5Vwi3RmpG8c?bB&}O3v4SeLa+cBU;pUm&N2yx7*Y!6kY`UCruenb zs~+B7FZTuBu`7)kLDz$FOAcbqG`V+%*5F#KxxMa5wsC=XBKpsuj1B8t%?t_XTdX>E z`W`dNlA2@ZOIL!*Vc-WY!$qg@h^lFME!YkcWROEvV3t8@HO#10bBiq#ZF}*Ms@&1o zfw<^TV3Zgw6YYC=r5*o8gcc>@KJUjf!6H1^}3IO{N}@x0VQ zo!WNXn>^zUbNp%apgVh5)k%N#u<+u#;EahDp+-i+*%1pX3wc zPiAdY2!qW{8+v^IX%CH3*Xj&K^3S-0ibQBz0-3+wLt{Aq$~noP%zTJ05KTH7)mD5v z*zwbHAGE(@+pG@e1Mbk^KaLs9f63lnpa~x91?#)N&7GfrF|ee@eFl3+m0p@3xUKTs zCVE33HN{HzIj@MfQj-+w{=3BhJe7I^M!Dpi5q*{bMUqH-+*h3!gflno@hyb(x$6V) z&VuC&2zzAxI1?ob^7)qQ4>dj+jGv?#I|ZisL&HkMC{XBR(JFN%Mc17qSy@OuZx`Y6 zXt2>LDbPCDq!Qa>&5d#LXTv5|vfVQVd3<-F!&X@rKJ6GA+_XKwdeHmx28YxRkP{Bv zFlEJ#$3EcW>6A<_s*TT18h;7#XjvL~B=r@_BI+6{B zvEHJx=v-@BAqkv%24TfMb3&Tux9)Szi# zt*v4V`SmzAF37XSFg$TvF)(k#qoj0AQ_Zj1hH1184l=DQ|JX}-^$VMQU;>VuC$rj$ zVCbDE^Ij`Uo3=Peg+0KVez(61!Fm)cKW0s=YMs=nB)$F^&ryOG_pK}zpQ=UKx(SbL z`_eJqP!dx$%}eZ}J=3EFhlwr4`SX;LAh!`Uz(%j>1u})&y-Z2j<*@NLUsW{}jpL-G zX7{-B2f3^27()bGGrGdfQNsXIyrH{_c|9?=g*nI=fA;X4_5LC0H(`~7BdD}AJlZ(U z@C-H?>G|6zGYQk0!WLLEE$>;wHR|_WPI-+cHNBv1SDyC4G4UTTfDZ}}tdOo#o_(eR z=;a;2mw3E_exh)Lt(omPJm)>!+_%0gXpVH7JMBoBIPN2M!!wA)1a=2M zr~pg;0xND$VNehUXLeU$NW4``H0$LqTaQ6p*YFTjr!&a1$M^&Pe+HW0*K!=ItP~y4 zrJN4**2({UD`8>n{2xQcU?sWVF1MKtjg708R^Kh}^8%*T8MoBvLUSm~14cLMR}EA+ zM$%0X-e{3Ox?jOO<@Yb!#Q40wF(db|BWJn&asLMPZm4Ek2rL|v^1C6@C}g@ZyCJLD ziT_5BF(DWDK1ps6J_@C)mk{Pbt~OXT5?cxS((HjhISgDQ9-FnS9GcSOS9_T$(X$qz z);;EUIDdj)ZZ~R^T%^;ja!Kg%prj4P0}5%2p|8`UI~gA=q|Q}F0iYv7BLSSJMWe8u z6w?UYnd>ixS%g@hvJgqTC*kW;Rp8nh3#~-X{%Pm{7|X|q&naXaXb+drMe92f?4J>J zOGc3C8h&byDGJOwRkavKBP;E!AJ2=vS23sr>BoGUV3r0guMSIcs5vR?-tA9ZkbUnf+VMoGG3)7OY^qKZQBtp^Dz{h&c-JRpw(J{1TS@Hbs zr1$&hIUq1={B2)F0y^pa`?3_&OMs3Dp!ClFtd0Kq9;uxwtAPB7mFemB4GO^>uLA;B z^6bBDQg4(EEaXS`ZXx>yvkPvqmL3+2{|>T^p5)}-MgGto;<(lTRlpbSNzy_NCESSg|n$!hLO#m799+9aQnmD9d zX^UM_AkwV*va!1yq&mxQkhBLKDSDgJqY_SK zEleg`v1UsOCIRb=!oC!9?L>hmweC6S`|6Xr$6$|E`FkQ$LylxIkb`%sAZ;4w2Z~siUd&7t?V#kGSzf-;{C&<&kUq;v+@{&uwO1Za24i*lc?^L@L`SteI~Z?V!{Z90AtQ(HMpb;qNl?PCC$JS)IL zA*B@*p=R+&XWFcl($91HDxpTTAWAcow-P?geEy@YEstXzDp#~Ss$|c4z~vSl7swp< zAxn4uK8F^5mYjVS)pfFM+Qqx15l*h#YAQ%;F^SRN3&6lL&Qh7dF-0$Xq1yzswz3ZH z;A!yvY{fNISNe%pa)U&U&SmS32IeTRpY)*^(h89@EUU7DwGZ? z8F5~_saWF68Gp@lL(6xY7Gb#uFt#+D7T2v(l_%ZjVMLkEFt{|{6km}PSy0B@&PDrR(3Du#$imOjqQ2RY;PJ&CVc9l^ z5;lGr{M^Yp2!~f}E<4BhhG?Dzc;gg!YxX5RT<=N!G|tvOAnpDCW?W{CS=;N z*+MCYHsH*J;{S&tfWJFSXA5)`!F|1C0ha^U_Y){#@caCBYTf3U*GL<@S}} z#(ZYPpDWUu%gAWr>Y1`@7z32zQRLLB;`+6L6}wpE_VL7On4bBSa&X+x+@^-3f>=Ts zT@W~1k--)a0MxCs0mfl2ghQq|bsdWk;>O1Jdb45(DY2h%tghN9skIKC8;h+P5ZF?< zO>m}oqU+V|A1`h7V6rMES!BOiN}aRy7h!vn>C?(cm8R$Hv2Q1<^&xFGx)W*3wdeMx zf36Oej@Q?{fnL}CRzlriqNfm!T`4XFi4R(>I#y9T`6j?*ak)i0=-o;-Z@nFsD}Ei3 z_bGR5R{(M?YDC4Ctttd#fO)76lNGAH+~UaZz4$nr=`{w_*?*&)gCITxWR9NIDs#_+ z+3{ny6;T_)KjIR;&pF5s*D}#4dJOM>|6tYkH7{P%B-k4K78m3l6-IXZ2^rVyf#r6u zsVqW1;GDwQJq^+gXX9|4(1@q>v#$CV)X5gZAdHW*$rcA@oLK0M<$x3?Z3bfAF( z2~R)WaW0eo1Lje!Wik}S~_aO8hwNPDl7@6smuMxOA>v#_z1_#HV1EokAT zh^!3CHa~!CfjhqXy$74G>*$6>Yru^>pn+U&VAh8D+y%O0$N@AgRp%q{H{7Ficw76~qTfk$*h*hj+56PV6Yv{pEJ3Zc)9 z6A8B6QI|MEWdhhaKhO-C%g%Dj?Vi!ozsqh*RPm*Zc~BzkJ|Esix)8Uv)WUnDgpbW# zXAalw`FrT}Z}bc_9=jBQ3f3m5VEubw=l`I`)XmV*8RjyV7!@hvzwupK#&51 zWbDya3#=11PGh01B_-wPQ`?Ze;}^jhDhki5lI49wH(wZ5#v7c;ku&)pC0slk9!R4d zgn9FmCdD>?OmfBly!5SpgRY4dhlYzRV6-#@NC8Vpe0ptS#zbB$ZY4R>i9M#0sye3_ zl_}Y0C0Qcj^tsLf%&C$+b@pJ`xMn+H zbVzELYjYAne5?&8aE3-&P+?eB z6lm9&Rw4?#AILS6R~|}(r>?mA_K^gzFv$q2eC=H_)N>D%LjW4^YR~uBEmaU2gvq#$ zUKriyp+NjL)nP=cr059YRYx`nm$R$lP?(Q5=h5)1Rj-_?@efhb8@b_A_jp`OM~<~Z z{FvWAW{;%P3?!7yVf649;{cY^9a|Q+{H^w~995h3;M=rcwxUs^f~Kgh-RuogFHM_C z6o7jvl^$htszVPV#A4lzjG-2lZ3Bj>^Z+`oqN==Z)YU3OKE7^?3G19mTaYsuy06Aj zlVz~Q8KX54C-zQ8{iH2Jhs$1Mp4a$z*`;}9{f-IRrm13|Exdy4W;XNQroHoi7&jJQ z*?NAB+<;;a0#N_uQg^CW<^nZ^P9f+=y7Ew*K7Yn-JNt!-2C(JV)7#j3V2S-ydAqiv zSS5iJVu|~2fc6shMIq;<_wx7kzUUo~x@OkOE>a3TnkIJMvHNW!#FLx9#Sdx_Q=uPZ zWwVVZ7&@dH#sO&h05qUjHh})zBR=zMKpf|T`Y}VztR=fk__Z&iM|jLzKVZbk`$jDu z`+1KnzWQfW|*m}1Ht3)tektqr-v88Z_ilBp=c~I zXv+Y$3^Vat&12;8pAUH4xHQE^IOV6)fy+l)92RB=#Q5OOE+|K{t%6n}{>jk(W>ZjY zEEtpmu!%g_CBiOe;Cwmts4xtfJLFLxqgGkZG+GdT^84}5gz)lUq`m3ttC;YGJ2QSl zdZ%@$_&yhyPO$1OS)coqI!MAxLM2juShDN2_x87Bm*0@Tc>2Wz2`ZRLAlTFX>j?2j z2Gd{Gj(_1je$#G_5oM^$w!KKE?>R8J2R;xJ#|8#rr_oPU$v+l60q3MWLA!@6D!)Ii zUmr@+T9TJ2>qkCHN<*0@SWm>1+k^Lo*Js~f*ZVYn5-oOletG`!!H9{tCoDd_=YAob z-g}cl#kix$rj+-_K%;7b(wtsJxF=raT6x*j61*B(-EJ%q9tHVEz*$_zQL5K7R1D<| zcK`Av*Xfnvug6&bXD(dhq&9y>C6T#au?C#7IbPOnA!K5T7)w9)^ zz+rg|;-~RwlBtEuk8w*#G2To!yh%XPuqc`%Mw~C)QDX5pEv{8}wb7 zF=|JKW%2HyR@zvBH%SX2N*{{QthrVKop#!dCMS&#0?b{D}O$(sK%fF|v$bz~qC+9!RCCv?;%t`+i#Ga)3M_Q#%6UK9|P;Fl5 z6FB@VxMRSjpj-hQI2RMDvcQwYs_jbQ;;Lsm8AxoXp}C0XEUz)nun7WO ze_SZBg&_`BVCB#7bxoTk?Knh%hF9?s_94Vvn-KimiK24pM(V}y%iwMq0mMo_8~b8i zi^ozi86E2fwtUBdF_a)nSK??+Irbz>}{!;Y15fd*dh@Yki z=q4IA&EX3K1V8%~GfCo|n#dQw(oh=2+_J z;g!eoXtKPrnAarpK4z*YyXbUTIqI|GyXqa6HMlk24AY-na}%huR*#Y@N8j~-s{e%X z21b#-wWk`^4s|iM)zyK^rY7}`X3`fc_@`Xs?%H+qvuL`jt{OvG`m3;eFGVLg22L_g-62w3)n3sbYnV^)Dr%+#ArmzV=j5_v zbFF$@O|0veZ+n{TY(Yt+>J9=x7@^7!%;Q-L@}3f9Nxl&&kvB288`*SU@R#5% zGrUYSj*{z>kmkYUieMb0 zM148>DE%wJyc2x}9T3zq6U@*exH}6+?td{|!4jG8jgvndgr!9r0&dr#qi_B6lQBW*?2kwqX_w1Qyq?|s!jVDaa7HuFDJ!WCPp2m>)6 z(d%jhokUDUB?R(W$N^dqXA1k1T(fbzb32GjDCds;K?FS?hyYpxFlX6<&TMFRMpJ1{ z2VXY7f>={;yHEIjE)|8Ky(9z^x&tYWBXf!N#C}m>!H~C)Ih5Sctb|-{MMqIRh3eQ` z`@YDwIj}$dwEY>k&wyP6PZ&)ETA3VZm^EVTM3=a6RiIMspk^G}+`5Pcka=hoN>heW zmYm7OmIX=ZiM24>=E<~24&DN(qhz25<#Y!jLFlt{ipWv3(ub+iH)ZT)b=zbf|9qZs zZp#7B)sC$ssS;8wE4vHdXA-z5ru2-oSgog*pESF+SQbJn{6K7+x?%NW#U?bqe65Zm z>!ovEx4mD~tBC|Z*>iEn-<+)ysLHnJSy-UZk~)PypQx#%E*Z5_#o($PRR@d2Im1|B zb8KJT57BHaF_~J`+TU*f#y=~?q6F0OX;+B0SWSqktI%NxVgLu%fQ_HO(eNFr_a2i! zA5-57m1|B|aG%PJAb8hzg~Zh?R!nJX;NSB+bUoM2Q7|tJ^R1Q6Sx#LQEdrpzH?w?& zR8hZX4*sa3*<0tIG#UDV(L_Gp?X{^Qq6By`&(WH1YTtkLcK0p6`y!5^RsT9@bV+$Z zXQDTI;tBuC5B?PW?chuYPYI*-@Ep|CluyuQldIgdC=V3f@@1#zv@Z`XToX=rK6A%shkv0+hbpV zYzS}@7R73vHX7cw4K+3_dc2CQU=`aNc?>Pn89>Ki{Cg$%-B-we)kU}lttPiYeZ{}u z(q#WD2Jo-WB0&$-SzrM5ADwLa+DwhVL{``OxA}$k6P%<53Fb(nN;{uji9i~_+ld*q^aCtmc!2;fnjsbfkPH{zw1CUdJ`h#lfIlr?u~LtkTr~QSo5+wQ9J~HO=X)u z;muPl#cY*Rtx+^-<1W-M9_BW~TW@i!!Mx&VQ);+dVJe%JIPJoRbj=u;=loydlpy-J zFn68oUtB(PcjJF z?VOnu4}hklWzIWh8T<3Vg7HQ>SU`EJcF`Ba(?or;fnv;j&HK&(@2q6&>1K9JofdKZ z&+2}sEkf63o$XR_+gP^fHLzvaLX%`UY1uqb2Ka7HTQD!iO4eSR(>H{f0Uj|5O234a zJ&@K@^DZZ(of;;}e)xE;_=HhU0yGE6OwA0+4YuA?*WdmT8{FqHjo<@%JhGr~=D+W? z)W6&rXw*mu##$}nECevj3`8PMf&Wu|l-`|j7l;H@+8GfT7gt~-V-^Mo75RcAn zDQ<9t0sM%Xcz^{mDGRrT!cr8ja>QtH&DgcOv^Z811(-P!tD&UFZfTKBJ?TO>-3&j@SVgG*xZSGTy1;;| zg89W4pNI`jkbN>F;8_L3haLi&Y9#4Yw)YT)Mm5M~NIWXOsqbf4tTsonrK?1DQbuotvPwOyg_EH0x-XSK;1_f~gi2fQ17;5Se*l(0CVBD5 zxF&^{VmO(@{?{*)M_XAdgX&DFAEtEyy)8KaGdM&Wc?)cFgnKP4NPYh65L&WI zixE*2CJ=b{a$xUf4jqs3#o$?F3?KjyGw8&6(>ZQms~62^7YTV+kv51YG8wUEob3fx z+Ej>5d7uW8$VeFn63ZR4H&*QGK(njnav-WE#{P6?R@4H1pTQv? zYS2HOR?QwIlp1ZcR(LOFtMN4Sty~mKdv-@YzN-yv%#5A z_fI(C;R1XqvO40OWLe8)^@UXHJks<{<}FN~4R9FqYI9XNwvww+ah2vgFyfnZ+U0xR zqPmL&3tj%-@q_274tzhlh5yt@9M&heT^#9RKd_7U^&V&NC07KnX=}t4xWw)4DHZ6a z9Q$9)RE43PByyp9g+kjxcs557#P=J_mZm0~#hXgozamIyzvU%xr_SK)o^``IeNOC< zNj7vNH}?j)!=gCbk()cAndrieXw>MvOc$fcretEcj_psHD zL#Y}O@S zk%0MLekhzMGtjO-M`*DY)`b->sbBMhLK3)J^VDYxOAij$Umw~V-|8yY1mkgLqS%-6VW{B<8~7id?C_0WGf~^jjl|*)So)`aQBQ~3l>A%>Yy_7vv-TpOph4sTvbjr2 z;4i=(9e=c28pbk-T}Fj^t%?2~iVzw{iFOyu=IAkW&xc6hB)@ctaYO+`Tq+<5n*eW2 z^J5EKtiEbGk=#PvxtExsQry>VC@hEMadzJEr)-0?)U|kl@ECfp5@1W9=UxEJtkvk_ zCwQ45nf7{ION;iN#FNV!&k&iN{OX9fYRsV-y^amL0^R$*Hfk0~(QJo)r10w7a)Co~ zHa8OkRy5)kzK^PjWtXkrfRntP6D`6yPPz9ZAnsn3Ch2%M4k!9!p`qds)B9{`kLmCZ z!#k!2r!EtWSxil~ecNPd9m>L02?yoA*k~1ZS%dv`3|v)mcXUnE><`|c7%v=ont~y? zJmr+8FLSkL4rXIXV48=MI942ayOE0fB9YeAD(y25H-W8$)BfWUeX2{*Em2J~II z8G1VS0X%2<6=)jGJu8r{0aPpM2bZJxF`>=HW$l3#vt+y)ZC5gxTV0fRycbVMb2%!^ zpXT(9iN>Sf$$CZ1nuOwV7O4;85h}P;L92;ZeYmjDOWITs5oU`QEk>e`~yfOk@~jdOJWsgl(2eZsPsP1_e~6mrII4lr+c%LqBl7v5xAY> zDBSFO7`iHiH5eDOt))u^0fqrFQd0tZ?w!DL@aq>j(y<=mv+~G2m_mUAlW&w8=r~jk zXcrD@gM4|$6XUWP^Yg6gmp!Cv40CfV)5rq;e0d$6cpv(&i1}x)YM*iV4S}E0ESIsr z!r>k?K6$@4sD1w!-`%)ei9?MQ$ZxWgR&lqY9L=IM>^8+Py$(=I8!O3feJp%0e22Sy z7P~K_E-7GryX39acS~Ac68vNKDp+vQH|vDcHD z*NUr&nlrEL$6huVs zOjLXJ=OFs|RpY@oq<+HJZX-4HL<7^M<_TAyU{0z@YOj$_+{Do2;zl=X3c%fJ&dAkc zBgbPWHuL>g#;WqwOJU#%5a}RW1KASHJHqY@Rv|q5NZB{~v1V7n(??gO&c2eZ-J|z~ zbssumpFCMpBpECbXhuej?~@anu$0mr4XOjK8UmN1>z8_pHp33x=gS*trycQQ9*DF- zyY{diksU2v@POvSD_#}FKpJ;224=1ZsjhytuoS9ADjMxh;jyv33c&$^rHD|VI3gw< zs~l!yw5P_EB~x0g3EV|kKZE%jI-TVUZac*cPZ-3ak{g1=ur^Z|I>)>ZLLWzo9`4u1 z==Ns;+kyo3JIL!(u?EJIG5;!avV>-OJ*pHbW$99BFzSZzca_`*RbPXZG4sA*N$Vfd z&#UP{o4+EH2~Hq@Ut4BFm!(3l+!(_tjs*y&)k&;=@@!~C0FO$JGS{#WwE_K=5>?X5 zns<)?ey;#QAl#4|-A|geK?ik)x9J44fD*degf6q zGy7EUi*#9%c2wdQ==-r(uBvmp9sOM;U5Zz-&cSB$=YI&PtN|Hcf1g@V|5vWze^;PC zTiqnJYn9)6Uv@ZMSPg$l?FKQZdD4>4rHxIfbVXt_?@-Mvb`>&=@uPKZtKGcDud?r^ z%s-boI~UDmzesR(PUxZbmU5=GuXlJ~dTsh#c1-x%eR_p3And{!W|SSxvH9WDi7B1p z^<}lrl&C^{-jU#?c8Ne32?82g4riDp@wpOWvuVDHLAV@s*tNSIp^1(}feG-eR8HcG z8-8!o*+*Arr*lee|IM}W9WWrwFxA9u==!}&is3is`I5Sm=}>j0P090CRvh*hec3*S3xTR(R*y%gOhAeKTATOf0{^L|0pKxV_g^xW!$W& zhX5Ui%)SD$N;fMtxtT-K-O9Etsk-lL3+&6t1ee~7vvBc#IMh@^I88{6MYZi% z73Le(wV-I{_oVG)V?Ovo2_LQ)H>g0|4@9;|z)}o0WR6(Z$`Lt7f>NF=&9F8)RBL&rJ(vS!qn&A`uuLJi0C4p8^+pGZqmN1aM2G{xdCUPsc314itTo+X`OhP*1QiO{SVMnt~q2Tl${pW)hx{BTl-k5zgYcipf3# zn)G3Y?_Y@@+4WE-=L^q7eWVdPrW^v%;*8#Y_7TJh&bORa@kqxe9>hzuE$9-0wAV~% zU;t}IU2ZH3h{W9y7*<7zDd~L)z_lPVzk>}JIjn^4O2ng2J zsLP{QKAUynWHY}XcxPJs3?`3^cM{00(w99Op9tI<#H=NJx!f!Y0=hdO`^d)uQFBRr zU(`LKcIuaRN>eyHLKr@6eKBp~6pQd>dIet=c+8D(hRhMVr091=RMET)<{}UwGrT*4 zp;aU*vJ+aF1FPJ?!y)QDd|9R^G~kKtUQ=+j;yZ8-DST)8;-Ab9f49r8m?Un)q3#hT zd$p5CXx7bC`dR9WJ79c#v&6mzWgv9-ZHEz8de=i{=^po;9b zzo}1tk3`^KR@jq3BM}{F3CQ=aJ*Tp%v8nCfcH8VBf^+2NEG^w*HVz9-hZ6 z7EqVOBj8K$`mQE?h^v4xR%oS%2#7QI_yf!hqUz)#ktAXp z;D{u?#mGD3upWg)vS{9W<;@ZOWsy+4w}qz{d$bB_#g4tj0)st>^0r$6+}35B5%r33 zwwBFKOgGNuw-*_7Q&v8~Bo_{7Fjm#mthRfuuWb zQCIsq7ELn6C2BmCB56s!w=C3+Yld-;@BG#vW~lCdQ%`mkNV-wH;kyv=ka>L2UWoK; z^7Rp%K;31|n<_E16_YK%r1E08&=LCui&$eu>MR0rS=up=A~+b!PqQhwHe+Q8aDXHI zSzR#2Le9#{dOUxzm)&{7M9D<+V*Ma!)~L&?c2wF}Bz0<={=(G0%jEz85Ns@@OmI|m zbaJ8_hD3}^h?7|YJE{}a=*R40ZO7XK}ag~pza1Nt@twfTh z|PAJ>+8M*12R+abA` zn0x$A?uakv8m(0qbj#WL=~lzQDrJ~HnES9pNk4bw49*xxV`FBiAAaJeqIacX!hi2K z^x{|T+EH(lXVtPnrhS68f6!%k2Ycv0#b-VF!Mc^-+9G~Kc&)#(iEfL1nbt$*Zar7^ zSSa_N)`QRh2l*OyEcNe8oZs(V%RubcBj~-KgXXM%zXkpCz5neNl&Pkt^4mP-w_12O zgfbw!B!`ZgW(!7BFju>$l#v99|0$6^j((loC4sq5;QI4XWIoa#&wO{?=7)J{C@(2T z#+s9(lY-;p;$=tnyMs8n9H>exBleZ)$?5tDx0YR}*8Ph8=3pzFl|$a+G$`PLiDf>7 zgR`dO(oxXFR*AtFl|m9hC2U`FX3iP6Su<_Jt@xkb_XFUI!83>#8jvCqKEA+Q22gry z8ys(I64H;U&&&|*%I#r0*kM9>T+?mUl8WpbXefo*` zlq|p6|N1(D-7GFNbhF5ZF8#S$5{+yZq%F4ijL8>J1Xk;HgZwDC{dALq-|~} zO6k@|i#%_1me@W9_Q;EV;jD=5kNFss$c_b2Z&k^$UQ zy=2aq@T@qz1uzf(G1GwEzTu{I4@MrRC7KHms4YDUlbcrYGs@E)oPvJ$%CSN5P*BCPK6B#&&5VYVud&ECH<1)YWChCYf z1@HJO?%R*_`bCYk^iKPBpRN%fb=KPmD_pQ>P8i#E8mCewMmOtN(qhP*hX%i=;x#eG zApr!keZu_1fZ|#<*lfk#!WmyH@=S1$@f)Vp?sw7Uxs57@Pm-ko4nn4xPa`0~eOJt% zf_uH|KMW|y$g1NgM=%>DimLadYEi$tina8G0f{w~=^w{Hg8N_BMzgBCJDJ>F(HIu2 z{M+djZk)zdd*v%tW!wzG7{nY#F+{leKBqj2N2#u^Iv~NlddFZb^h&@a>pK7+zHo-i zjHI+qs*(NM^)ua?X{vyLxmqaZMSI*-6nv?6auV}O5U(b7QQm_y^dk;%MKRb6jIP#5 zAFp0(eA_=bBUR{SWqM|3s~6oL%E_;b55 zvL)9pxk~_K2ZuNb8&O^U-J-|?wf7>cT)Vk2U-Tf;isLYIUFitOf5JSz+XZiKV!(DS zXU3Kb<*|~Sr4jdr8}YaQ1ipI(#FOi{3_G+aJe9eM`+>)9QKv z-3Hb`!_&VflKu$>MMn!eM+;{Q&p-Ipzx5t}p+Z^4ZcY&8jh*3eduKszjD#)*oJ>A9 znL0LB*;D8w7akck@nujiEh^H6%ZhZ1!$EL|n3HJoCuRTHpd=|3Ol;wD+V%LOH%q&K zj}Iv94(uU=GS@oSC_fyp?fPth4uXjZE#c*I(VcCWL)t`!uP6W{XL%+|-lBcQOAZjp&#RR7^ z*CcRr1FVjB1Q0uI^7G@?jRH0k?mJNFwhSFXF`oXB1G1-1{Lz%VNb!CWBw11f*dyVd z#9rMG4C zl>w#WLj=9Aq+L+1+{UaXV8Sr|vp;9D_SwT`(dOb+i+HnA-jH@)4E?G*fm3qN(f3b9 zPw--PR0}SjE?G3~rW!kQlzQDbvuhqu@e^BFQ7wRizL72D_P5(Q&VU|3fi?=`S?2P$ z#-(pQX16vfE{A^`!he5QM;wbfNI>t17sPiY|6f}2ztJ534^0@YSDI0mbq5NCk*IA0 z6BQ#s7rWN47vu?S7(|wl>Eaf!pZ$bwnN*mJ?Bn;rbU7hNrw)zqU}e2{%K7mwyQ|9w z6x(5mhT71N$~GO2BXUT%d05o9PT)k>MFAg9{4nln!!|J;Pq1z&0&e3#irCO+aFp^E zeY}1LpYP!^K~JMMDr|FUXwk#s9|9Y<_KU}#6V>FP$#rXAvs!HtWC#NaWj z0S1vV7tr8Of1bad;Ge#4qJi?+i!%t@$Awn;fh3(w;d4Ry zfcbl4Xj`M7qDEzRI6E(ER1uACch41S+07%dFojh6&4{TjefGKi5g#em!8Pox8)e!B z9W(@N$yUv|7Tv$QqwmBK*MD+N(nHg6H8><-+HF&IFiqfz*Mibw4tzAdh^YIVY*J&D zG3M_)LVt3D7EF_#u-Z^SyNX#oTKMgXgRAGrG9K!}+F^6yaK%*hd?koyiM4kxr&`>4 zWF0v-x#_*u=vZDWk?yt=S%Z}DNZ=9$hsiQSsE1CwO?AM=!c?*BgmfwRzLT9=iC!xK z=~aMXURgrr8<2{9!&mXr)3>7k{<@^Dc*&d^xJ>Gp8nIg_zrou#t(0TqrjI2?xAFbU z)k0d>+44iNmu2Qy{Y?j;N zC*n1O%b41Gp&NDGH?{tn-Bvfnpiev;k%Q?S15|oPP;6@SV#d#62riIic6g<*{n<;GL&)m@;6(@D2>6T{K_#ovfNN&XI|QB?-=NdaOl$J? z4^z+a11Kd=Q2#OsItEhzKfp}Y!~Q>vd=(poIYk^kxATR{PiyZP-~&E>w9ZjQLBYiX z`1hNH=W^CR9W$R$Cc7SUM{fR0^vO+UTwQ9geJ0$?TjY`9G55x z6@>M;J=VZT=5C^qK^h4O>K*)GG^xE`fF!XpH1Xn3$zx(s6$Jo(Ce5=Y;zlu`_qo^ zM!Y6YWTv1ycy_3udv<7~WQfU6yai%jJU&IBrdL>QSXca6qFS1JC`o(6ePMaUp+~xA z54r9!S|==X`Cyb^+6^7Kb%xeu&b#JdsLrtyuBBL}9@Xj_CXqQYMM9=9H$DG=%SmU5 z22r6!kUC9*Q>Sq}O_2AgVQ5-)E?T-4}n{nqDaytvWVYY))C zR4n%h_0X2j?zn|<6SjtN*XMGq0+hZcxGm9#U->T}!?21DQx!~cj)L`wa&PMbf88~)XAC>T3BTRD-+={x9K|FiK>{@Y~&%7nXZ z0mg5$E-Wple$n(PO#VA{9ykWyBdfXy*3uZT8UM>5v@?3l z0dHKonCO+1&6qP)Gs9|CwCFcp_8bpdxV~@!ur;-{^hpJ=4d11x3av?04X`VoThCJ$ znWBa8Je;jn3OP*ciQ6K!o%!XaN5O*1lnnT)7KLszfT3}+$}c=>+p$tv=?p9`%4r>| zcFUx@F3s5Ih7Hr?n^_h)Cu|+(<4|P8HvP=0yA|uL(dz~)IJ=n6cuxizE`#F@uSIc^-A#cz$@-5#&a3x7@A0lUJf{B4Ap+$4(D?_vcw*6MDo++cLZSoe-V>Sw zMBxVCD9BJ$0z z!&WYeAt zi+iK%=az52-0NZ@y( zb85#fOFz+kDELjVivCo@>Z=@e@ox;fiS8dj_-WUauUWN;VCgZO%*yl#Mz7nE>mT_M zEGEqye{H9a;NxzH4RqjY30j=7i8rBDUC1DmjG;1u6D*IdttDbFh)wr%D@tfQ^G6z% zn_q;VY>xz9aElg!@dO?Wkt%_sl*~^b@j%WE8txoWp^l^*bFXG65UmNW!n>z8EiV(LVEpzl!pwFkx%a zckC>{;_0yL>0k{p8)^`2nB3k|AmFi?W5hi;)dQ4Wt1@xB^)Pz0Qe6!UG>g33 zK)!yDQ1KuXi<+tm-X(jc$5r4K&*cbNkZ-*fV~*2C&FHkZvsm zz1Nu0WgYjm)wiKJe}l1-yIw7kTvm-;wgq zqF+%!1CG3@+d(GD+o2=3=jFf>@4N!sG=;m+sd6s6i>tw)#z=QaB@=zOP0jx2Ch}Wd zDTxY=Aa25`RW|#`=^;9MqZ1TMwD1R>22cGn=MNsiMXrrq{-Jq`OAB*tB|5>kPNf+> zJu@nJy2gC?Gaz<|Ym)_xOC5gO(*6S}bVnFk?&pmOi#pank8QmdR^dR?kcL`>fs)o_ zQ%_6-FxZo=a8DO&;M$);d^&WRdJo`>k_C~W0RAQ2KGr~Goy2oz4zj z>N8{o@`Ofdf`z_vbO3Cj#0_qwu^q$Ajn1V#G8rH%#5SZ>1?{<^-qMLViAFM`SdyFf zT{Ip!CfBv9s3M{-kJW(+Ejn?g@vRQ6q)B03UT=NDjo88-$-IsnG}-&wQke&Zbi^Z7 z$W)k`NijT0sJ07w06nbg+AbEz3F1hobdg3mpYJHj*v>S&%uq8)Q);~-^23QQdhF;kPZ!Nry^!9dmKiaTqEusQf z4RrMEHJde-X>;t6k_GDlC+^qu#%%6FZH@^5*Ubk3l;{4kFHt2`e^VA;tf7=cC?9Xe zB7IZ2Jl+-V;=QU4pf6z>SH35g;up4n+u-)Fy|Ul@{XI+n&E(7~4Ao?J0jRvP9)~g%uH`w+SrR z2$<4Q21poEvN?9N!dq1ZC@Omif#X0l|5CKhuzh zg3hfJR0CMxGv5kUR#sl_S2{X6eBZoZIey?il7*vrz!gZ}68AFFbO7cxEYv%#9Fi|I zb;?aj59qcuH7l2s+%TYYnT%Ad7FEiDj=w~2pCLMC8?}{@y0rm^0_cRbdg{iXN#XOf z&r`O9<(Y7dTAb^(Eo}@IU`vXWDleA=(30V*FQKzBp|Eb*-AfOJlE9h&VqW8`&j9#{ z6s&%%-p!hw%*@CYIQ8f@=Odwbtz5OQ=1Aw0>CGX~06sDjCBPO(Qf4P>DWbHLxdK&N zRWS=W{gL?qvV|<5ELv)88z@???nKGfxR?r3{4qoYKVw-zI@UqUR!No`vvmGedJ!C> z@e&#;tQLE(AK}5Ag!Q0Ei~Ts(cks9^6txj(3=EbaWcM{rIpJwIgi1mcSXlqXY%lG2 zOm=~Lhlf7CNS;*F!?=G5DxYK%Sw7gfOfsyxs@!*eq#3^bZh<1kwA%!t`a7y*xwB&h z&9aIHU6uW*xIsdiE9sqfGYd*1iR6`cWrnKA+dP@u|GL?lL#qlTdiQq~ZB@p^DD@eh zI8=!mSzm1h>WEywOMgJuZ}fE%nFy!K5gc2U7Sj{=3aN75bjk_k^}VRr#p!rLBP3Am zZ|^f?5P4LxeZwnuh^RBk<*bEuG>8@4J?I3gd7TyIg>6ggaYd(%aP4VoO>D!tJ8BpW zY>B&cREa-%*2BV9E_xr}@R=~T+k67(#)MQQB&Vfk;-qi3-E#(Y5a+(BI|N z66w1vL&wP5J`YYByVSrd6`@YMJk7w4O{*5zZlPDrT<%$FLAG{7a&_H6Z}K*OId}UZ zjq@VbCcGi|2T28|H`>iVJN6y%|85{q$wFx@z-Bc9*sT8Nk!Ii>5ZIa8+1fZ7lL|XH z*gE`UA4&Mj*EaaBDWN&?VQi!H$1r#2>Nm|LUk;feJcjn9Q$t&Swb1XfG7x+kWJRsc5X;A-->$E&-!u zudVG2c)duP&V`m)Ot;34o}glSgi!@S{AzGFBR`kdYfUYM`Mfsnc?a2pv!?DF53FF% zs7i(R3omH0iH=Lc^z{0FFk2A?Ap?LBJmcl{+4PxsorYejDynftDUEi>`9^B!MMxl& zF$Os;R{C(NSaAiv{|IA`@3($6Z#`88y4waA7j~WHR;8oW z-ha4~69H4HaSC@yO*7g@-@cyD%zLE#qRX_--pG=Ll;4aTh_VDDTV0Mxcohf$#tTut zZtd;331IW84%s6aU0)Q}8E)+(+00lqz}vxM$I%|@*IICka!q6-zuOIbo$qxo%J0DU zFWHOcKgD9by@I2Bm7O|eI%IklXxnP}%gly6;8!Pff@a?g$rNUF7~88wc~B$9%)iXd znsmt+K`p?2;}-at>yAo=>Fr-Uo*xHkF|7b)5bz+K22QTg{AV@qf7ii3+tm;JHC6{G zX?mbCVEAwd%Mr+}7u@{22=GX*A6W67Y&>^Ido#k_ zX}o(b63kjRx2?4dD4m1cuLXAdC7jiYgn#X9GgmR9L9Y!Z+y}5!lC_6hB2=}h^+a~o z7g;65p%U~NT!;eF6Sr>OQQwoofvytpuwSVrUHO+k<3J@HSNg*`oTAJcxs4rqv@r?R z4O1?z4CNJT$Hx^n@Mivc`G3r1rakhaAvqtYo(d_v@-*03eB&o%FHi#DW^d2xbX0m| zy;1GQh6w&FzRkV(J(%aH822!w*I%@exY~ytNuf#CCa;K}HZ})L!`oT+3(?33sjO2< zhkW6=KI75MU=HRJZe`P<4)v+Z4no479dSb|Cw0hlqc?t7Pof~P(W!zgbIpnB5ETdu z!JW<}X^~)S(eEz7G%2fSJV#77^L7i3SXZ*2!_e$R=k}DC)`m4nSw~+!g-T~U1BMUZ z(=>-;eW5n44|QuM8OuFB1Zf;DCek`bN6H47nPqNkqywA@sZNR1tya_j{5$1 zl?V{`60qh|r`=YxSVQ|UX_x&B=}l8U$D)}}H9z z@p?_4DDE!3zMj&Ma6x2DQK2#8-z#0c1wXe&`&!}B-4Ym?d2%n9I*Zg(k<#n$;oVF8 zFz##q{W(?RCrP_6@KoCaYV-e@cJcSA22?X;4J?ceok)T3XD4H~fA+}#2!aJI)EqIW z@eiSVl&=>y-V@YC0w(88Riw!IBk}<~lrD!ZCTpoEPZV!|oozfHQ2T)u7gVWIh%YV^ zr>mY59j@o=uTLkpkU!{n#tp#o5ftbLVoXv#VlQD^EZl4@M2V~6j!YHAUo!OT)wu9P zA$AaI>B%>lD~_ADge_xDS?wQVF-84MWr_9MUn!R`i%^$4WpXPL(Z7f>7z;>uQLE3i z?h*%6K@<~NHMq*iQ@fAQU2MY?VVkV9lZD{fy{IgcpZ&#>O*JUo&EC^&s8NcP2DH3J z)z;D>6vj5lwaZCp+K?d+??bkpr9R*jgv;zUG?+{LG^i)mk+^Ckq&(r`pGcNCbzWve z{$dxWKlH-2xkVIh{J{HF>UR<8n)CZFTYusSiq!M69io=~SGgw3*1ZlCiN4h^E_r5^ z2Uz12dIY*}n)8{QNGrAJ>$l%86Y2ew?gMMMm(?I8;R<07WWEeZ0&j>+(K@gzbI$Sn zvHJFmQVNDOD<^a+BZV~?{h&NfmnAEU=zt#eV+H(^Br)p4CXaMTl|c%)FX3-r2Yq(& ztB!LS!F5kmD3*DA(S1n>K_S+b1&(sJvPz6>uq2+nd^v{F=JJ-dIz%Hvh%woW~mFV$S+Uf&3Z&i5fG8!X}%%c z2eFf+tBfzkWW)xgN;eDV|e%79H2hc_{MJZS8K=1#1j%%11 zgzC+>Me=+$R&Xu^d-S ztV|ZoAGGEj^EM&iybLDy!PwYS=S|zq&cU?nr*bv%e8>(66!Pa7BVgDN^ZbRe9 zOV2diF#4kFog!de%jf48s#{#KbgUo4G0FP#Fc=_`;=sX58aO=3FAxIiD}Hr!O1npf z1ii7H7#HH2^^@?UNy|9~X?VJfA8MeJ^5G2AZw2~yT_@}aEG#yA=w#W#j(owzp9;;8 ztKoeMnt;@dHT6V;^>ZO0uY8Jze1NH&abeS$zZ0)Yx2;tq?ZaXnKr7+`q_k{Ad7ZKM zW&LHbe)`*D?fRF+8uLm{$ZtNTY+vJN!Yy?2rMqAZH=Xc2%$V--!J*ZWbxDVlyj zDcA?3pCdgFMRQ{R%*{k5QODyYEv$z&d9F*7<)K zh54%!1Mb})Ppgi9hiypN+L-?1V)D;?0SVtEVl_D-G-3XaVd4&csRXd@ij=?O1^%&j z|0B*``tO4O?GjL^67W&*Pfz>Yj{B$4*%TX}t+q=8kR$eEs0`rL0bx-%Hq98VB9K~F zBpfi_iv+4r;9bJlwgPQV*(WWIK$v954yfeHA*TI^!3b^ z0V`G92|#rb;@T`33eRz6#R=w<8zL^nw2RxL;%Q&#V9Z!6q?{O*G62_WmEP2s^!EgD z+=njCNSg?G^X!LUMLOKa*z|>lW+jh0vI2ZNNMYH520GX)>*q?<6Vi=XU+&665!KqF z2+ask94GfkrPHQhIua+l-*%A}3eM0AX)5+6P;w`Y_qG^YDk5EVzIeBdipr2JJujO; zswHEXI!m)@`5B0U+>|FnMm!YYt<AEURO@F}V zci<+jy{bHyT=@exepPy_{uFNkD``@gJJ=ZztvO~%+ z%V8;oPZsnBU9UrwEEyMzr}+eNpPGO?Hl22cGiaZR&{2}NT!#*g%ocdA%U1*n|P1CtO|agj+*NGZmHM zZhMu&db`rhrE_9cp}BKiOFNC z<((lA)y+xx1rSu=$hRVln4$X&L zh&`}DkFq{jY!+iVkWjPyE>a-~OoI{4no;>=g%rD|=Uiqr(@y3cko^a9*|Fg6Hehh_ zjWXJm-8|5U?5_88waNW_bhX74=zQ(}@=2u{7*Z+-u}!Yi%h>z)`P+6Rc zhSw@P3!$honi>!+VvC&Qmh@yML6xh`ZK|VU?_#Mj`SJ8CIvbtYExH7$bQ%*!YsFEH z_DQ!(H+>J%dhiC^{0lD9yUrZx!C3!eNX%>ULxi??>3 zPu_1k3kFN#w-3ipVk!)hZ9|}8(LF3f^|Y&KMeUBKw5O9u^+-XwRprtUsKdQfkhBS8a5W|DGrjuslN_cf6bm09u7E*4B0PTWa)q zWVUg=EH}B=NH$o;UOh7#T}csz4^&pH>-c|5zC-s;Qs5RDE=67NJsd|t?Mo;SG^Uxl zPL~F>IpHGjM^E~w;sc2&8MT#Q=)YHQOSZv-A^o7>l(6@8sgyvS0l({{&DrZC&37Ya zSs|sbQ?hdOnnhPB&mPRJAxI;RJ}>=DAq9_Y^$|`(V=a0{$5z|Re&5^H<{A%Y>a_v%&PT4Rd1oE>_e7QG8rkjNKOc^J+y+KV6(Bx)9?^VZ zTb(5!bo^c|_(;qn-%YaYOyMhiBKhY#uzI6#z-He6W!wJHhQ4PFZNC9Kk{aNg%zwU3 z{?E3e=mgwd9RJyr{IenXM-VHBUo#36$CVF1Jf`|*^u%xhG(U}+5xK|BS)>8R>eNtf z)UrRQzCF~Hwe=$(ksh_DYk@1|VLW5E=T6zPylcF#C&0JOPy3fVkzg7MVq9jzxPpto z2l%Q<D38n&x9t`3^r^tCZ$MtS-EmGBj;V%zacn{PD#&yvw9cila|5|!0j_LUiJHVtI@Qn#-aB09FQLv9M8 z4HoW-U?&-7JzmGe4;*fUz3@ZmME4BH_q;g7p)9|D4&}Q z!U@k*7U@S~=npOA&?K27@_%)Yx~1TNR6rXhH`GwA8e;JZr_4cxYiJsR>bO&#Hm)W>F~K`v<;RhRV#~Z6W;En<1TQ@sQ&NgBY&LoVvVH zdHbYvLe~N%6BRAv>Ytx6ibE_~Z%tJ2IcZE))2LEYmKM30MTkSNubD*d;S1J+*`ao6 ztklc}Im6Q>hqT->x{jBJ$OmA-5;FHzxaf4NgIk$&m~p>gf0Rq5F~7j ztG02@9Qz+ua}=D;^o6lp^A%Q+$ZyY{@3Sa10Qc^t1=>bt<3>$fA2VvhXss~@DO}pc zA4`c530yJ&8IXJS<0V(`@b3Qcv#TJD_hS6Oeq4bEQ4ql`vr|IgTG`f2suc-yq$I+# zLUV+VLRi$W(=grA_cD|KRBUzMLB`mtsA$XS-C7-9lH?*dZE<}hK{!z3PKIj@^cHWD zGx~9$l#|9)lk!_ABKJmi6OQ3zHTz*A_Gb+xY>V&=-YQgLqHzsb_sk^AD zj(oEA4d1RG6pf8~y7o~gy9P2tu3PG=*zO$yJa3kg0UfPvxL$lb9NE&W@VV{Pca_B} zlb&;lnM}UupGKA~TeWW-%Uhhw=+0B5>-7gG*NyA0$w43MCzujn<-PO0Q)<>y9K#6< ztv{{;u(YA)QzW5(sDV0A6=o3@5r7T&?HK%B_(=fhE$jkj1f3t_&-$qYav{9P%jUq7 z&ddipNY8it0)poSy!sej@cfk^J#_nG=PVpUF)I-eu=z58By%;E=dg18Y_IG3bwrw$ zfrJc^)q>5mu8pkMBm*Gu;MKq0A0vq=$1*=A ziEm=Cyhb9tuTpb}vt{6__K^eh%U^O`)~4zc$#0<*d;_AiaIhn-KX5(58S=*~`Q!Af z1$@e&n-~Mcu(#5&LmRu3c6?iz3RtBQbbuZUs?DjxLyc;BMui+Nvykn+1LW<9j4zvrmG~j zd5>`kUys;J^?f+$wd&;tC&wmVuFY?jMjct`)rz^;@D`wZyOJzcRAycEt=%NR$?Gh_~TL zkYyFE!N*qE*NQm9IQQ*1XNf)VF46v`6W_nUM;d#h6Iw_Dg!w+UXJGFdE1zK)nNUYK zy9!=_MF*jT-sB&pnJii9vyZ6w+O!;b=tt66XOhRNCDG$IFS5S%lO z;nVB0f<@Oi4v@D$v{h?*%qCp@FoS_NX({z3m;`q@^T+K5Unq$RAlD~=CBV?$`Bu>Q z$Ut7|au;yhynWa`z1}>)^9+ z_@KR}#-iX`S>8yaflWk?f3)$mrx}wLuMmyteHG*e@FM$BT@1@15U*mWW$p%%xbCori7@ zp{N@uhxsBhecV`eo$uDtw^UB)ZQhB`?r-^?kHwIGJl!Rm6NzkgWXLbJMdOUQUPH59 z9#cDI6bX&F)O)}Pwvwgj4Z&sQUcmnMp!&E{mTHibRR9mFRiGNh`u}=4{_9zV_6DKR z_yJZd3Hb%Csf2-yOqW9W0SA^-U}#TkB>9WKQ}=(M*^|Ja%Vwl4AT&Gm>xQe({wWZ^ zvkCdbn6_{_KnFGyF7D8flG=9ge9YOZQj7kn>dg7L@%IIkwXO59roc@dr4?pzAH? zCeA{GC(gWtLSSXY^eO|U*=VXkNhC|j*Go04)&h?6p{jk9I za()P*IGRP}m4z=}=g_|ln-Xof?r|$gw@~7mN|{5^=LwmVTnd&hSJ<|!9rN^ul9V&s zl+V9*^KnU~6bZK1nbMNC;70do#d|XOnT%FhEGmuqkQH2lu<|R2yi#3@5wSlw2|wv* zS8(xLwQx?dd=Ass6Ev%%_rI+V@`SrNID+taPnN*8=2=(AEGos}3c?12a*7e1h8wHk z9rs${ATpV5$zPt{z&-V9;k6WN5KEMUw0i@hMLh|bPoKTVjeF6#bXCgsTqWKY z_DMI{3$YB}&Tl6oDOH+JRPabju2b2>5gWE0D#1H+nJc1$gaO0vFu!|P04K%iGe$=^ zI~cF?ytgZi8s-%-c*Sd!fI9`;W)7NTo9wRDLvG&_X)nLOCR`U*A7#3aKEY3x6Q7)!Aymd><`a@mC7l zfIXT-Px>QP8kY3q7U-kgK$|t{NG+wg$;B8@yXtT>wefxb`V6iIE9-#Or3XO;D+mn5 z2eRUAUbGg@T<1Sn@wbW}cHCaQntF~1S^&$CI+kC5bwN+-nug_X4dmd975&kMaeYa% zHez>4j)c<3Frfjy2Jdf;dw7Em2^F>?%lR1Bv6uA}YjR)$I6nSKBxB7%Ammu&$30fr zadc>s_FExN(>+Q;X=F1pwJv_t4#PcgCR9FM>3J0eqvMd1tY$^<$s#Njm^;^3&c1)b zpm~=KQrtI^24MTLiaW{}vLruzxkqu6_R4xElhy=bE~5wuHg5NpK;D!>9HhUL(lsNC{c)UFa-{@eS`g7|dsos1&;R7#Mks5{vhxJ%UXmw0H zU2x_3dR-VQ0UM!6O7;9!QIix}atvZs`LikX6`h1xH{ZT_DCrBJGAxoF)3gpXE60}E zj}I94F=Bd4Yg`&x#bz)GPrNo?`nuZR0k@F%(lJ?Wmyt?=sHAv{a;o#h?ivY$h~0Us z>w>s6evF>Xrh5o3T58hP;Qm}-itJiC1AQ4S(|#k9u5sKiXe~#OUW#bD4c4-V^DdbAg$FFZFFE zNwRcOEWXAY^nE4CSJ@3GQ%5Y0Lrdq+&7t76w8sttnWVm=`<4+_WHFeY>xEHMN_kU3 z&2n$Q1e)Ydp{-*g?ea&zF^U*oL(P8IVp=KYOv~X6Q3$SySixuQrH(|en57o2gLDfV zOnLg3XvdFzzCPe~APrdQ4!}zP&xjR8TPuAVeHCK|$N$j`BbEM1&edEFG7zrTK|(7K z)K97ONhu2@y9@qRv{Lie4zKw4n7&!h2hoT*YfVLBw9JUb(PSdyCiCU(kMk{P z7Y0EgqyIFR0mcB5Y05J2ZSB6fV#T)XrH2XbiULSeQv^(V7&&w;uJ2&siDtrC)d@+Zu=(gQ zk5(#d>44VAK1)B3Ug`;K#HrH`heEDdPk%qUXM#y738d4EC|DA%j&2=Im<-=$y`_ks z0=SK*>9hFa+^|ygFbbYqi{dnqQCGQ?XStCVGOxhVXc4x^N z;xpmm>v?uFYjBmo4B8_dgoXMXoW8I!kuj;^#BJwdW%M@!3RHgb#NG~=hqcXh!vU#Y zvh<)C>~cXqp!2(v29daZGKputtgPr&>thtkq9Bg743`VNqJpcF#AS7=@bl>%q5Pcc z3UC|uTK6H75}bEJDc{}tVb-}ptZC)kxdEnG5ff_23y#}_+Kf797ocCG3!+L;Qgo=C zr@4TCjSqCICnUrD+q9 zgQ(ONKce-}vdl$oo~(8vS4DLjVtlZbPg|*C#4sZkDR~e*%+Cc!Pq#78Q#I3`PstCK zn(JljJN*6*zI<>rOg<74Rp|x!f+9daMSz&P(=5|AkKP4Oi(=fp88?@6txC#=NTrE9 zBH6K+PBbM&I@QN0xBu(==-~HsA<&lLMB9`+Ht#@nJuD`75PN12d$cFH{2z&OY5I{1 zbgPA$VKNVwKWO*<{Rvq>no#Wz@Ln;9`QO;Migs2?wwA^=|44@XP|5%9Wg66;ba4mK z-w_}%=qxKru%x6i`ud}~25M_iL$2h51Hn|;qiXC=ZZ!(P7b;xP&qhL5v^r+mjGALqTg^7k^{4buj^cJ?P-L5#hPo2par++V88x zs+Z_50xxZbap>&85_a~Q{F+l<|L&h93OgU@+H%pGLhQ)=b* z9=amzK}KZCKLkWskcQRo?U)l){Un9ObO};{io({@@V=g8%1NW?8qif`dm+ z?>aPWVP(!$>ClzO{<5-?3uxARU(m;g)z{-`bP%GdKvP3^6kTXnJv?$+FRf3>b?5~Ye z)$a^4eXTtW=`#}{3u{$HFs1OVFULTv_il-9Ds}oG0(ns8XdQYs-FWiOX~l80E6JnU zsRZ4#TD6-G{^g3*uQAUzu81Z&_+$@`m!#S!^u}KvT7X}qvYEdZ$_CBs7Os@TuI4jO z9Lo&(5pDr6?jpm?wCcii}dqbxD~R`BB|zzk31saMMmxZH^vTli;SVDb4)gqCrRAwhTLBb zgyxgqbE94@tj9=YG__hAJ%Dm(-yU95T=An7GU|!1`Ynp9VV*N$GY2EC z+01;XXlU+bILZcIM33@wJreDHlY#40wD@OOc@lDLt95uQswuM~0<6@@cGp$LFv}P6 zkreM%fwI21B*Ds-zHxx{?%@n8vL=t|m4T+^QEF-Zy5jLpRwjrbdV8Ff$A!{OtHveQ zndoR@SqdH!r_!)dCf~(gOE^}40d^Ut*k%~ z9^jZ`pW=jqg>9X0(CRHVd+OHtq&szMDrfYsptWoFa$m~$b#vADUqVJ-tu?fEf4L5q zMZ3VTv%D1;jyh(SQf*i54{*!&f3SS~#HV&bQt+uCM%e>;Y((_P!Ob9R`zKdnd(4L$=%jSFaFI1j|VKd%F9#I4F-u$-I+^c zaTOhcZqOerx``~hvzN|aXUDKR!89(V{mx-9eOKSlYE^GVuFh&7j<=~M*Y5+HLtus$A*2`p@8uz+cJG@=^7voGtVv>7MfwOt<94@p_&}Ng0!+M zx;+_In9Ws?3$&R&t2b`u6(39;H4QH3m}7P93Ac^xf|FBceGjS0)UN`IK^RmYjVH>WD!%7Q zxwk5}kuNu)e+QBUGM4Z7`9$zH{s@gg3;zfWX7%*DPqUsai90BM{d}lPMZONEhuzmk z6m!f5h_9-<%xDfwUa#g+<9h77P8@}|T~Xn?^~RrN@5IrEt$u7P&T!7k;H)k6xv)Ij z!#6s5jT9f_LWd4zg({Mw$fX%hQa79X9v01e-z>HN=&bE%(nnwM5vq;i@6el|r;O5FZlq2Sc$p6Px*0Sx`zci4;I#6sTzip^XCSnqH2Q zdWE1^u|ULKUJt4b{YWSwm1wG|KSz|+$^nLbiN_Kr=nlHmb8SCE{<3yVHBtH7~2G9|*iCPrbpuAbKKh#a2J0_AK%6 zeYq!Kxb5s&XBgVTeS2uS1nb1T?;Kpe7&72Mym)=&eG@~BQhW=&#@oxL`jYbpc29le zmja*I6UWG}o$N=B)_-R#EhjH`_x?i}`Oo=Hz{fC4V}77M>GCh{?2!qYA5`MO_gM@N z{RTC8S~q@h>(A=_ZE|qz{N^gswB3-|MP~*0%M){J=BS;ax;;W4VShfKz9n2)xq@4l zUotK_PS{SonNGYtx?kdd|17H*LWmN6G39E4}u}6)8^b(w_L+3&Ez%d!mYe=>KbU83~w7YUKY!1Q=rnf^(Mer9Vh$M zn&^xKMFAYb_a-6;Zh|?&9f0dF&MEqo5J{u#O($$~K$|hhDp*TDW+GO2D$z-2sXx#p z9b?Tc^zwp9r`2Q36@5SY*_%4~%f6{t@>f`(DSYo^XZb(4t_@ z=>ir-^iotFVHK`@G%O)$MO`SZi_&A1S!T1c{zC66++^6)uo&YqJR7!c5Y|LBtR}x` zCdRE0s=5YDa^lWl>|}2p(QI2yeB)Y;NCl9d$2o3?=f<1#!Zj(|3PoWT7p|bM)n~(! zX`xh!5JBe$AR37!Ixkj+(H&)fWBaaq1)ghqCuO;Vo$RUuGdsn`;HL~o{CuEgrwQK3 z^Y9}7c=M)7S?%S4_n^=m4QbDF%W#O?`zLl?;m%1huolv_Q5f#*oW*PCt6&sAF++1% zLmZk~MUb{BGxUoYY}X(+~7otswS^O-hH~juh_A|8dYy&r;}8!A$!+z(mAf z2Ht;W(Ekw89?Bp%XIK_AXRIbiGdSn2QwFW>5nXYPUM`)t3tcZJ?J*z?n?KT^@QePA z%SQSZeFHa8y+<3*no`FddIR}it>oiL>j?Te%@!!!&jK6l|Du&R+u2#U|Ep9VsjTg| zB80|!vZS&d!pSDBiK;QfPUk|2o?x3%PyhgqVk#U)?=d4NdMTjrCybl>2o)>HLzutM@A-iy%*%BCybFK3IseAu0ecOwg4DhS- zw4>!2m(x!4n>&G1th|4ND`GOtH8I3s@3lsU&$!e%>YIV~%Q%>7CV_gXyq zvMLKEC`>c%4Y9xiOTR6bI6M;3DNp}YGTO+ zqCjw3r*W@Vg(3tnOi zANR{PeeWL8H)L&eH?4QdJLGYLaYfzbN}Zn^;`CGbEWAYTdvd3vY6Oo4Bv6!Q8gW?q zRmA|AKaxEpv4InE{h~8R{nUgyUpECuuBCJlK&s+H_D5SjRmhw-*`#PYi!C^-LKskB z6NH#W&rYBTsJgFi9K^D2(^{eRfSb8T4Wi2HPJpCSPXd8$c;wE0uq+Y-vV5H4-B`iyUlsHlo zeii9IU8bhbPk6M?hHxRE|iI@X2C91MSh?J0pI`D@#Yah z+PeDiqL5Bq-2^&fyLezvOL>;as)6BxZPO7uis7TzeD9&?LB(RIRjisPBFngFSkZe%bu zDDCb2{|wv}!N-nVa3b>oOFxwVUE=>o;Qq4_j{5g)fPG^fn9LALO^j_nGvmzyY;Qn-$dwq3fhA(_pd`x&kmt9-R!RPF1#@8Byz zNoE`3BoP95(AV4aqQ+zJYRu~1Q_+P^k>F(ztEYgiR!P@1-!Fe-Yp{FO+43V#uT_UK zz8JbGj4E!yH)CyXonkz%EY~j73l}O>z{AMf_hwxb9a)u7S6q3cIFcpImW2bHo8VeH zGw1Fubr>AyFk_c&&t{p(BAxk;Gfvz{=F-eN!05xsw8z^}p{RMR%7`j1lO-6d3YaBa z$2LFG)$go#kDxDXE}#FR-A6z=z+8*pw0s_#R(aY&X4q6Ur@vAl?u#YoA^(eHvjdL5 zmP})mbA$Q_ooW9Xd7e}=2`P<|wt=o8P|@Jt7i^eYgJtbpJmBAYAQi!~RwLti)w!4d zu2#h)-N94ZW+|ME&wYvWBfQqVeguq4obD^liTbBQYc&nr`=p=WeU}QJerWn|UpEBL z=;e7rnQvkzUfKy1Rdpn&(w(_F${i-zm5^(ekozkOo?h_M$&)*A1^a4qICU;|zyg}{ z0rrh_E2Oe@8`DS*)p-#=ZTR>m1!6pN2br^(S4KMH*!dh&QEli*keB%@_g_kA7erJ6_`evtfpA z#D=)?*7T|Cg7%~joypk^pTn;%xIc$l8!0pU%RBjn8UeV(BtHaCfxVqjzF+?%SHRqNP+Sk6xDOx#(56|y}My?epo5=IO zpsY0}`zmgnyBVfN0_|dpJtt&o#7WaB|i8~qtkg8z3 zf2Y(Q&-6UmjGNK-C0LCU#`!VEGaRKL;!Hexa)ViaJUK1fxh0lhTL=HZDJwTZ)Ni_J zJk0N_YxHi5)ebr%8$jJ#0yELA*?TXQ0nfU(a2lZYplNm@3n|dMDd+Q{ns!0pEYY8Z z2`rL&^(pvLXlW3>aDw+SY!x+*7$&{*!01}pYue#7+A<{8r8uho+V8s9-FQ@K()i#B zKqjmqyCZ$kSdvs51}x2VoRHgQs$>qG3l+(n{;<}3O&PbGX!sZWA0n}JDo?cLni{|+ zlj(?_Lr1|~i(BU1H+ietin<@n-OMic#563}39QRdZNJr180vFpo5r2m_i`TXucI7| zlcEeGUA>dAYBHPByD`sonuy>PuTWlQM&tR!=VKWr0wm7yu#~sko(x_p zVibk6#tbABuQ2-gwvQ%g!fW!K!!24 z$Pdt#xkJo;C4)aMQ?{Nv4N7nOCdif25U5M)C9u!{T2>1R9-+(Mi;VTuD|ESPq^G}x zGyc-D9wiwa@`&_L`HJ%@X?oEb z-y9{2SnaG;aia5Mw!1Mh%83U=%=gglzoE07-kA;0fWwIz98S#tHD~-ioc=ZvM$nV} z2kAWT3j<`ty(2^*5VKbJA6TEHT!5YB@dQ1*ka=H7 z8^{%DUmm0N6JQPD-R+XD1a6>qg5@cLg#N7ire@7-cL?NmJpYv20#JOY%5=X=65Uo5L$WU3-; zIz<|In5Om=+7CL=WP?`28NL=&zOFo<`}Jm-Ex2Jmnuus(oR;1Rsz@-`F(H~Ji`NSd zbVK#-N?_!8`xSyYS-Xi8#-6uHGCL5zO4j*_CJzC0ZVlVUFfo@uyW@}H1kHiG;UCNV zAt|lrid+JoG(%tk+0m1xCfYX-N#&KoDI`iK?Io)GIx(|fP7-wA-=J8&Nx=8>qkQGC zhSuO~Eh*u-0n@RRCv~@%xrxUwn?*gCdzqaYXxe2tOaU`1)8d`X`H5NNx=%+7LHJEF zzI?;5hppy^KjmS4UaZ;`Xp=o8eMb+$gme~**o6h{pV54E7Pc@=5xGC#3n+_UGu_i= zOuBD&z-;O&_X1@q&ijMBF{O1W{L)Z8B0q@@qUZ~XGbt-&@JOzHLnWe;H)fYy9n|(S z1r|$-V40-kIigPjb}hsnRFasf!jSi7WOxzzihzG0y{qM_yKlWB`?1uBWLf`b3p0f=J# z69t6*Pbg_RQ~>$c%kQ&nD{GdDAB#S}tUtjUp^w6|=S+)^Nn)hoE;rsId-5|PPK*pB z4dH_JEx~g&SI~f&O*^!69T<~t6+F&d*7Fr35;|IQx3@8ad5Fh?3w2pXZAG*LtK~42 zHSUAgFcMYUmk`}u+$=Mty_ce0Y~unl>;wC{+{|tSQ4P4}$*FGw#GN*xTG+B6LQdZ4 z{;7iZSr~xKkTL86G-$LU3^UJZNfbtwI?Nz%wcHfNq6vA{073l*r~UyAeZIIQR-U|$ z-u680hc4!nF-Ev;mjcK9?e$4)^tHgD;Oo>YJhko)qnpkbgJ()Ul1Dd3WR}kDHcei*{j?1dvK`wqK zosg-;EXC^8?0l`d3}_Uq2+^e&c`>@8_!+7GYz+R-SUO98Tk>p?=SNw%vEo<@T1?im zo@Cx?>>zm9ZD?(}Mbmp}?WO8FPHkQX?|rG8qL8@gEDwh9HPa)|=zI!{w`=OW_RF(B z3Xrc+*JCR}_X@B^WK)qd1HvGW9E=b`R;vG4rKsh%RBsx+JaYQ14jA>@Zyxg%MKMcU zW`r5!8b=%CKxmGBc-kS7hbHY6aGdA(dTh)jO{+Mtql-AAMK2o&zP*#O^xITl3=9PC zWvskmwFcAo*6%1-%O*t~RSsH;e)b(uNVPVBl8d~%18xDP-*w0R^f3UmfTVN#qLmURO z1&88)$I<;wS10D+yr7 z(fvb(smHY_->8k;5JfIx77feM`4N|-^cn5&6!q`*N-%nvKc<5$ zK)m)%B#l3AhdIZfF3mE4diEI-_=Ii-DMzwM_F)}1SP=VdQ6Bn6q3D!q=&T|g#qlm^ znb?d=O_6k1#!P3UM)t1N#MmEMZYgJ^YU2PZ%d+riHO@$jxXZ47as>%vE;l_K__vY} z36gA)e7>i)*t!yQY9!49N^~x1_?! z(KFPmN^7M(&G{rYx`Im@0b8gry!zyDFG;NDiWKMfENAn2NHE=`eP5?66u|-ap||TT zv=AW$Y+tZ*^XzKOIhPh~l5(y!Wbt$$tG=4c!a1eUMqye}UHXB{nZL&raX5!m61N2f z{dmOQgyEoGot%x|Hlefk^2*6Ofl%)2ev|%9(77UAy~a?;+*tOPfF{(t-vUUgBtHM}OG}`2ssq-WVZ12M`Ozi$V9lr<>mF$Rl6ssxEx9bRmehqs^d5nh zZ151D=awFq{+PxC`x3lu0TVb>@XeeXdEZDEdd16V~<1{g$Pdv@C8{j0<8|5f*zKK*%y1l7h_U3c|`T z2G)N~Sa-CenG6Su?-Gnb3VGOt@3R>^vW!-pQ3NIc**K6T>)xd>)qCJ$*5-MU+$R4==IxT2OpO|p9X(F{ylD;5Gg~@Kwg4>@vvRjjnw;azrslYD8hK=OGdv($SmX6$ehI{6 z;66h}jT5nJLaHOH{$O6L`O!g5O7#>sbL+xCa*v4*eJFq4#KTkPYWrw; z7;N>Zx{#3>oN{ARIVk*$hPwK~velK{fVwyPtuLi=*TxOcM6xNI0<+PMOB-^b%v!%O zDY~nC!S_wX5zBQ7tzHX)q&Xt_$Z?!{D#prK5i>1st@MMuT+b2w&c1;LuyGA82c4K3>kal@&a1HG5Ntw^I&-i_024r1qJjGs~< z`rheu*_@f~2)9yHaSU%%<`F|+ApWgq#sUSNw?el6@3SKq5L`}3$i6w`qZ37-1hGF#KoZLk&f4J<&2FG5pho=UVcA z0k;yxCl&kQJ1>rw=Ed{AaZjTNgjt}6WrbtB{ER=;C7qsi&dc^eAE!dkjKEkskx};+ zR?l^*_30n}cm;^Ew3dI3maA)%-_gLUo=qvd8t|uocQxMOWmRj^WAXlHD7}L*o37(d zd&vNypYV>q-E=m?q=;zQP!6cIgzW8aN3aGRUa&Xd)^r2hn*Mi3uK$ql!ANIUbF;q` z;QvneB=|kFI4V%!gii@qk>dgzO#BtA8xn!2VkV9JJ-wa9_C(PCP<(2*!h%M_dwR!G z#m~|71yJ-G~hhn zWE9iOx(H8*({WgDvPjni8?msrTW{CxAH}2kfPT;Cu{#*rH7$>OnP|$IH#vu;pU>zd zdftYR-bwt}+)Z5f$o$7XoOBjdF&RxFnU#F2Dm~5(?pC#H9=vLP&Fac#2mUEt2wLqK z`o;Z&iwXm2&5F*Ir_6b<*J|8vb-{d(OdL^!Z2WIzi76_dRk1#*NeIzluXd$3%r?LT z;*ds}=Z@#i41jm@-n`oi5mMFuZ_QUiYQt{} z(uUJap#8(P9kvJpceLOFI$Y?Atw1(+1a{O?Xr#uowh%MS%lqe9YSwwJe~YhAr~lhC zG#HmUn)5yrTa~kAYMi;cN1<3y%kz(I(TbwBCt zuN}~9p9$pU3N}uW6{e|CD8?0I*(j@-nw)x*Yqtx?J4#Wo86|jt5ZVH9AIP@iu z=ocla5ZBcc4H68=c0XQ>Rje<8@Db0{>x5B9=Ey456hmT8{xc1Kl{i&g2Y%6_+VFBnsZQHVW%gsmoZF;>wkcU` z+&@dy;yUxvw;KF3h8$nZ;1+qh#oPX2`sFh%sPacSZR#KSOqI~F+Wmf{&ruh&r7vow zbKa1fPXyYXYk`tVk^21#+B@m-n$KbnV!a;evC!` z4TpEm0Z}%UdiPPzxItZ^*f}J3YTr~U^&n2~GIZ~$#hEGa$;)WVcn(+Gcw4JfpjpmA zrayhWMtVsFTzo&}+s6Sp1GTqn_7MeCRBVb>m>L=;E(jLGEb(u+s6KW=<&F7&9%uUs z{5cv&tNOcn;cML7A}iBr{?hl$1mo-KCT(q_Ca)SAh5RCxfg=}>sl96?f!aV8HyASqqTyxr;+%mUD0o`i!Vn z$2aTN%dz{#D^V&ySce_=kRH-=TVP7#J~RMDXsg9^Paa^(g@m4Rw0r9#Z@f=6bp}PP z#@&@V349-&zZacjzMMBbX9a(PigOnOvG<0miNIxo0?TE}BlqyGFma1fppiwX^#^xp z?d@!sNux|@9c(3BSa{H%0*(8`RfIt(trX3D)Sm<04~v!qylRNJPhtT){zs`2P& z193umzb>Xv)g0Z7(>_#~!aPgn8N{xWW-kw+btLoH=tRSG$26zDjHKVU{HF7%|JJV80yib&8qMJbMw`B%4@cM^%m~f|epLiu3RTpm*xqRYa&9uLW~l z?mP!!tyhTg7gbzcmJGTipPkDnB*KerfoXpN6g9nmP4#wGq%1A*?|5Bo$X zO-H^T1T8*1j;Or&m6;;n0KC&L!ouCs^aWVwkt_B42_+mZaC~JneGPu$^+OFZH;9}o z=*=lC7MRLKlVNF5Hj^1t(%ARD4DS$b)g$S(@D({vCL(9b@vav6;$6grEgb5XDso~i zk*3>?yY;nLa*10;#G||on8oY4ud}@PYo)03QSum6w9C+-*FrVY_%r49JLTd#%`e5k z^Jvu;ti}2c7;J?iYvoBu&B%ftOor@at7kFkiYB=?Mh{vpk`yZtwJK$`ti8IJpLo%x z*_z1;uW1?=gO+o2atBUA(wVFM9N8o}#{2M4 zct;_&C6SskA=rGVDW@Gpmmss`-E(JHYhi#;$V%d-R zxOUKjiUmH*EkbuQ_L+$^;u-&i@+{Z zzlaN#-+!6R{AtQf`o;N3!IS)amLdGuaC%)CV>RzD=n%;3MK>ziHSVmTaZKn zhs{@G7AR350kLr`wX>}S0`=ihnwwTUYH|~k<0hNebMAqc{&g?dhJkqCgN`C+r10Qt7|O+ z#?53m)~{j%2vgfRs%iJ&RtQ-}3HJUVB1}bE>Y{%8+vuFhcnZwf92_$1hRhpic}cot z!@EG?^SeOPIKDZi_(yDq@~8u#~Q5R65GEi;&4eYt8lvJ()Zk`2HS@FCcPUmaU{7 zAOsjh?Aq&~j)DQ((J4*_5&;^l(pr?o2uYu*z6+pXR(`$aD&RPwOWx;b@dz+!=b>9P z(1ZODWl6SxFQ9#^q0hqVa8IR?#jVFSgLNZftl=fcc{aJKO>4{No=bIsgh&!(bvOSQ5j+Hg&Yz@WQtv$QtEi;jcXccIVNEH zcnNlixHM)C^uGvrSZnVe=XP6KJqa|pAOxI+Q6So#g_$7Kzs*6uhf-z{-5`JniH)HJIO-{!A4k07JMgg$aPPIJxKv$Tj$U~q59f~I$`WTRw`I&?&zG9N3Rm!mw`PLoe z@uii^xv?c3+9e!H8srsf=eern*@6FV!6fuCk5jiwPTc$ho=qrBKA&zF32k9I1_`}- zbQ2yWN#R_VqgU8+`P`US(DFSIn6wJ02h>A@7pT_reshYTTrr}q^%na30;754$yS{} zqAaHuUB!YjhnyTyF-I5l))ep$P~-OrkCP>D8IMe*ZwMQkd~Pp)JEB|n{vlimF5?=& z5as`l?)wkY!~gI{K63ywxCC~%bp~~$oe@cptPu=!R|x!2=)@!?kAbk8xu~8C(ecYGpi9%=6X&VE=c#<2=dUl5@tyC+ zcFOr#f!|~6SwcxbYOQ|Rd=My}8TDrdTh^f5lTU{y_<;BQs`fx0fZoswFkqaSZif(z zcPF424!PiU-sO2zAy25Kxf5?f1DlMEJC&DC)m3 z5OhTpEm49)dc<*k>pnBUlVSPYBdCgUrW#A`P0a5@^$rrE<8n$*f3fOXk}%qD1<*o= zMU%RluTq}=F^>IiyLo;ndf-`kFd1&{>@w@+3a7;-axYw|XR9?yosII~Kx>mIE}2_p zW;$EHB~*)z=>+pqoyQBY2sCZ}o!y@|Y#_}~N!{$w*?)2oDUD`a45Lc_w0O1b_viAW zAPe9}$KYkh@U&{b<&|;fgf!diLwHw#CAT>)h7S>%yX=KF_Y?LMV%MXfHtXX`(i1aD z10l@v%Ke5=t`!>ErkNd)sKE~J3%{{rkW!l~72jq-9nG$|)Uj++Hfh5qOieSxT?U0n z>AvpVFh%iR_rn2~8Qt%`JjbBOUm?wQabh3JMUTu&>w?Wesqt`yHLVndn!Nkdgt_=N zRWA1lTMn|{&6FfubqyT zdi}!}dA20OjY@6mddq-+aozcaX}hWrvPq0t&?*Hk}eO0?v0P~}uj+W7oRc%rQC zg=%-doKe+|KBGwop(U$K3mXs6xzE@F-?>3(q_JRk7&YBzbJ`h4Y^~lTtF}5Y6&c3o zFCg2T;Ld`{%Ovelu`i*LI@9c?c-BJ9vhV7rKW(x@%t<~4us~AI@KYL12ffnYwkgJn zCE=>fe*XF*84q{~jP2?YTg@q6GyD>B1+QbF%T(#J{NSnG`J4N5`nF$f;JR#RiA)h{ z`=u+&wC5nY3f~#Jd5bvH%Z%9V%MbB6Z#B&J)z*5VXo@sB4fgf&!$H$9S_28W;bDmQ z+0UExgH6Kw=uy^q$<||n-5fbuM}cGzlxmP>DhmAA-&1~4RK$*>9nUmHx%==%Ks?q2 zApuO|?V?Tv{KB4qZ+|f#{ZoGZG=P<;1LF-b!E+JT|I1G9UlK|DiXx^6D(KAwWt@?2 zle8)n&PACR6sB(lu*xfe9}X8ETE9bP7~{RQEAovLOwyt>1Ro70TxIJ77MC0I9#yxh ze%8=Z`gKS2u@l1U>p10rvPwyVvX}w0z!Z@is;w_x+YyTVA@r}cA<5U$oSKelH6YHa z(#)(;lK?}NDCV!T{ z_M{vuBG7$z>$wmXp-`A`gtuCZS`!+IcOrQl;XWkHv`-n*tzz=iQt-`{vQd#;Ro1v; z7x_Oisx&cp=^H-L1LDVgf+@PsDRvKa(se zSEn2NdO|<+RKYZT^_J$m6OwU;4QHZz3kr0Ma1CtD`T4$noGErvKQec?*$_y@{bgY& zpiNYhS;tGkIL*$KK#L_%$Bj9}o8IVK>6e3G1LIT~iyJmxAC30aZ1S;$6_xfkxg1v&5jmqX4$ITV6<5s*HhvkL7ZgipKvhnVe%nCif z`$Rox$pq1}rwcr=*vLxWxT%>uyP52qe1rKOsSEQSC~q9P0|4PpT!b|^9rsl8uIvdM z;exg(_ULMRm{Zc3qKKouVX_kBZvqivXE%oG$Y>ZlhdV zc9Xf}#|*=O>6=O(K>5*~YFvlrmrz*-X0dv&>nZZ9yEey>+G)bu>O(fOJi9b|wZBpd)ySL`4&K&^ncW^j>r2P28ba_VT~Sm(e9RG^x>%BW$%uRN z@zXM#*qzh>r2(xb)pITdBfOpUrxH2@DNZkMu2eAt;@MjN)0zZlaaeB{V zgfNp_ZUyOUAAT77C3Y{~QwBTQ`-6F2z6o@DjlVih7fg$H7vYs*Z#Q1%o=!ZV`B)s_ zI#rXmD$0L-Do<5@V^Re>n^T4g`9I)K2MZ9; zp>uqX98{q!iDtIpz*(6{Ym+f@k#VCS&N&xrM%2;V#AzRkEv4@pq@99=-rS_o-G!;1 zP?xBBb*wA4(q;MlQyQ;?r5{a3mZ0{|81Gb|#1)QELkS@>UwB~Lj>L&=^ns`E@!mLK z+;|{LT(PqI-<2X#czMtubGzqRdSbY8;7-oph6#^`30LZ0Vyxf(BF*9)8z2YNm>DUK@O5lw3s{J1747haue{vhTG4+1GivU^;5*Cky-S6Xii z7G6<^tJ}O6r^%J?KNHCdAO1VGF;o{c1r4r7FTm3Me?Q3i%gggGJJZ5{yJ3@p=U$=I z+b>_!h`+C^yr=GKjnE9k0r*s)i z|HiH{eO5fHg%^L)0%%0A?sLqAT07X9#9Qfdj4!+O_-8ar_& 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 v3Y#49LZTlSolanaTxWatcher + *

+ * Класс-наблюдатель за одной транзакцией сети Solana. + * Он: + *

+ * + *

Пример использования

+ * + *
{@code
+ * SolanaTxWatcher watcher = new SolanaTxWatcher("5QgV...sig");
+ *
+ * while (watcher.shouldRetry()) {        // ◀ проверяем, нужно ли ещё опрашивать
+ *     watcher.updateStatus();            // ◀ запрашиваем статус через RPC
+ *     System.out.println(
+ *         watcher.getStatus() + " | " +  // ◀ печатаем статус
+ *         watcher.getStatusComment());
+ *     Thread.sleep(SolanaTxWatcher.getRetryIntervalMs()); // ◀ ждём секунду
+ * }
+ *
+ * if (watcher.isSuccess()) {
+ *     System.out.println("✅ Транзакция прошла успешно!");
+ * } else {
+ *     System.out.println("⛔ Завершили слежение без успеха.");
+ * }
+ * }
+ + */ +public class SolanaTxWatcher { + + /* ---------- НАСТРАИВАЕМЫЕ КОНСТАНТЫ ---------- */ + + /** Максимальное время слежения (мс). */ + private static final long TIMEOUT_MS = 30_000; + + /** Допустимое количество подряд статусов UNKNOWN / NETWORK_ERROR. */ + private static final int MAX_FAILED_ATTEMPTS = 3; + + /** Рекомендуемый интервал (мс) между вызовами {@link #updateStatus()}. */ + private static final long RETRY_INTERVAL_MS = 1_000; + + /* ---------- ПОЛЯ ЭКЗЕМПЛЯРА ---------- */ + + /** Подпись (signature) транзакции. */ + private final String signature; + + /** Время создания объекта (Unix-millis). */ + private final long startTimeMs; + + /** Кол-во подряд «слабых» ошибок (UNKNOWN / NETWORK_ERROR). */ + private int failedAttempts; + + /** Флаг: нужно ли ещё опрашивать RPC. */ + private boolean needRetry; + + /** Флаг: успешна ли транзакция (устанавливается при FINALIZED_SUCCESS). */ + private boolean success; + + /** Текущий статус из {@link TxStatus}. */ + private TxStatus status; + + /* ---------- ЧЕЛОВЕКО-ЧИТАЕМЫЕ ОПИСАНИЯ СТАТУСОВ ---------- */ + + private static final Map COMMENTS = new HashMap<>(); + static { + COMMENTS.put(TxStatus.NOT_FOUND, + "Подпись не дошла до RPC — ждём появления."); + COMMENTS.put(TxStatus.PROCESSED, + "Принята в обработку — ожидаем включения в блок."); + COMMENTS.put(TxStatus.CONFIRMED, + "Уже в блоке — ждём финализации."); + COMMENTS.put(TxStatus.FINALIZED_SUCCESS, + "Финализирована успешно."); + COMMENTS.put(TxStatus.FINALIZED_ERROR, + "Финализирована с ошибкой."); + COMMENTS.put(TxStatus.UNKNOWN, + "Неизвестная ошибка RPC/парсинга."); + COMMENTS.put(TxStatus.NETWORK_ERROR, + "Сбой сети или RPC недоступен."); + } + + /* ---------- КОНСТРУКТОР ---------- */ + + /** + * Создаёт watcher для указанной подписи. + * + * @param signature подпись транзакции (Base58). + */ + public SolanaTxWatcher(String signature) { + this.signature = signature; + this.startTimeMs = System.currentTimeMillis(); + this.failedAttempts = 0; + this.needRetry = true; // по умолчанию пытаемся + this.success = false; // успех пока не достигнут + this.status = TxStatus.NOT_FOUND; // стартовый + } + + /* ---------- ГЕТТЕРЫ ---------- */ + + /** @return подпись транзакции. */ + public String getSignature() { return signature; } + + /** @return время создания watcher’а (Unix-millis). */ + public long getStartTimeMs() { return startTimeMs; } + + /** @return текущий статус. */ + public TxStatus getStatus() { return status; } + + /** @return true, если транзакция финализирована без ошибок. */ + public boolean isSuccess() { return success; } + + /** @return кол-во подряд неудачных (UNKNOWN/NETWORK_ERROR) попыток. */ + public int getFailedAttempts() { return failedAttempts; } + + /** @return человеко-читаемый комментарий к текущему статусу. */ + public String getStatusComment() { + return COMMENTS.getOrDefault(status, ""); + } + + /* ---------- ОСНОВНОЙ МЕТОД ОПРОСА ---------- */ + + /** + * Запрашивает актуальный статус транзакции через {@link TransactionStatusHelper} + * и обновляет внутренние поля. + *

— При промежуточных статусах (NOT_FOUND / PROCESSED / CONFIRMED) + * счётчик ошибок сбрасывается.
+ * — При {@code FINALIZED_SUCCESS} или {@code FINALIZED_ERROR} + * флаг {@link #needRetry} переводится в {@code false}.
+ * — При {@code UNKNOWN} или {@code NETWORK_ERROR} + * счётчик ошибок увеличивается; если превышен лимит — дальнейший опрос прекращается. + */ + public void updateStatus() { + if (!needRetry) return; // уже решено не опрашивать + + TxStatus newStatus = + TransactionStatusHelper.getTxStatus(signature); + + switch (newStatus) { + + case NOT_FOUND: + case PROCESSED: + case CONFIRMED: + failedAttempts = 0; // успешное промежуточное обновление + break; + + case FINALIZED_SUCCESS: + success = true; + needRetry = false; // финальный успех + break; + + case FINALIZED_ERROR: + success = false; + needRetry = false; // финальный провал + break; + + case UNKNOWN: + case NETWORK_ERROR: + failedAttempts++; + if (failedAttempts > MAX_FAILED_ATTEMPTS) { + needRetry = false; // слишком много ошибок — прекращаем + } + break; + } + + status = newStatus; // сохраняем новый статус + } + + /* ---------- РЕШЕНИЕ: НУЖНО ЛИ ПОВТОРЯТЬ ---------- */ + + /** + * @return {@code true}, если можно и стоит делать ещё один запрос статуса.
+ * {@code false} — если достигнут финальный статус, превышен таймаут + * или лимит неудачных попыток. + */ + public boolean shouldRetry() { + if (!needRetry) return false; // наш флаг запрещает + long elapsed = System.currentTimeMillis() - startTimeMs; + if (elapsed > TIMEOUT_MS) { // вышли за таймаут + needRetry = false; + return false; + } + return true; + } + + /* ---------- ВСПОМОГАТЕЛЬНОЕ ---------- */ + + /** @return рекомендуемую задержку (мс) между опросами. */ + public static long getRetryIntervalMs() { return RETRY_INTERVAL_MS; } + + @Override + public String toString() { + return String.format("[%s] sig=%s | status=%s | needRetry=%s | success=%s | attempts=%d | %s", + Instant.ofEpochMilli(startTimeMs), + signature, + status, + needRetry, + success, + failedAttempts, + getStatusComment()); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/SolanaWrapper.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/SolanaWrapper.java new file mode 100644 index 0000000..73a14fc --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/SolanaWrapper.java @@ -0,0 +1,88 @@ +package me.shineup.solana; + +import me.shineup.solana.internal.callSolanaFunc.RegisterUser.RegisterUserWithOneDev; +import me.shineup.solana.model.TxStatus; +import me.shineup.solana.model.UserById; +import me.shineup.solana.internal.readFromSolana.userById.UserByIdReader; +import me.shineup.solana.model.UserByLogin; +import me.shineup.solana.internal.readFromSolana.userByLogin.UserByLoginReader; +import me.shineup.solana.internal.standartActions.airDrops.SolanaAirdrop; +import me.shineup.solana.internal.standartActions.balanse.SolanaBalanceChecker; +import me.shineup.solana.internal.standartActions.keysGenerator.KeyPairBase58; +import me.shineup.solana.internal.standartActions.keysGenerator.SolanaKeyGeneratorManual; +import me.shineup.solana.internal.standartActions.transfer.SolanaTransfer; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.resultChecker.TransactionStatusHelper; + +public class SolanaWrapper { + + /** Получает баланс по публичному ключу */ + public static long getBalance(String publicKey) throws Exception{ + return SolanaBalanceChecker.getBalance(publicKey); + } + + /** Запрашивает Airdrop на указанный публичный ключ */ + public static String requestAirdrop(String publicKey, long lamports) throws Exception{ + return SolanaAirdrop.requestAirdrop(publicKey, lamports); + } + + /** Обёртка для перевода lamports между двумя публичными ключами (оба ключа — в base58, приватный — отправителя). */ +// public static String sendLamports(String fromBase58Secret, String toBase58Pubkey, long lamports) throws Exception { +// return SolanaTransfer.sendSol(fromBase58Secret, toBase58Pubkey, lamports); +// } + + /** Генерирует новый Ed25519-кошелёк (ключи Solana) */ + public static KeyPairBase58 generateNewWallet() throws Exception{ // todo возмаожно ключи генерируются недостаточно рандомно + return SolanaKeyGeneratorManual.generateKeyPair(); + } + + /** Генерирует новeую пару ключей X25519 */ + public static KeyPairBase58 generateNewKeyPairX25519() throws Exception{ // todo это пока заглушка + return SolanaKeyGeneratorManual.generateKeyPair(); + } + + /** Проверяет статус транзакции по её подписи (signature) */ + public static TxStatus getTransactionStatus(String signature) throws Exception { + return TransactionStatusHelper.getTxStatus(signature); + } + + /** + * Обёртка для перевода SOL с одного аккаунта на другой. + * + * @param fromBase58Secret приватный ключ отправителя (в base58) + * @param toAddressBase58 публичный ключ получателя (в base58) + * @param lamports сумма в лампортах (1 SOL = 1_000_000_000 лампортов) + */ + public static String sendSol(String fromBase58Secret, String toAddressBase58, long lamports) throws Exception{ + return SolanaTransfer.sendSol(fromBase58Secret, toAddressBase58, lamports); + } + + /** Выполняет регистрацию пользователя и одного устройства */ + public static String registerUserWithOneDev( + String payerPubkeyB58, + String payerPrivkeyB58, + String login, + String deviceSignPubkeyB58, + String deviceX25519PubkeyB58 + ) throws Exception { + return RegisterUserWithOneDev.callRegisterUserWithOneDev( + payerPubkeyB58, + payerPrivkeyB58, + login, + deviceSignPubkeyB58, + deviceX25519PubkeyB58 + ); + } + + /** Получить объект UserByLogin по логину */ + public static UserByLogin getUserByLogin(String login) throws Exception { + return UserByLoginReader.getUserByLogin(login); + } + + /** Получить объект UserById по числовому ID */ + public static UserById getUserById(long id) throws Exception { + return UserByIdReader.getUserById(id); + } + + +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/actions.md b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/actions.md new file mode 100644 index 0000000..49e4fbc --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/actions.md @@ -0,0 +1,19 @@ +InitializeUserCounter - инициализирует счётчик пользователь (вызывается один раз) + +RegisterUserWithOneDev - регистрирует пользователя с одним устройством +- оплачивает деньги +- решистрирует акаунт (PDA) по ЛОГИНУ и (PDA) по id +- регистрирует ключи пользователя и устройствва +- увеличивает количество пользователей в ситеме ++1 + +UserByLoginReader - читает данные пользователя по логину +UserCounterReader - читает количество пользователей в системе + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SolanaKeyGeneratorManual - генерирует пары ключей + - - - - +SolanaBalanceChecker - показывает баланс акаунта +SolanaAirdrop - запрашивает Airdrop +SolanaTransfer - перевод со счёта на счёт +----------------------------------------- +Const - хранит константы настройки +ResultChecker(sig) - проверяет результат транзакции diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/config/Const.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/config/Const.java new file mode 100644 index 0000000..26d937b --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/config/Const.java @@ -0,0 +1,76 @@ +package me.shineup.solana.config; + +import me.shineup.solana.internal.utils.KeyPair; +import org.p2p.solanaj.core.PublicKey; + +import java.text.DecimalFormat; + + + +public class Const { + + /** Program ID из declare_id! */ + + public static final String PROGRAM_ID_str = "5dFcWDNp42Xn9Vv4oDMJzM4obBJ8hvDuAtPX54fT5L3t"; // shine + + public static final String userSeedsPrefix = "u="; // префикс для Seed адреса пользователя по логину + + public static String USER_COUNTER_SEED = "user_counter"; // Seed Адрес PDA счётчика пользователей + + public static final PublicKey PROGRAM_ID_key = new PublicKey(PROGRAM_ID_str);//"BmCgGmQbSjkE6Zg8WAwhxDMNHiTknMYqTF4ZVMrPdTpz"); // shine + + + + public static PublicKey ADMIN_FEE_ACCOUNT = new PublicKey("6bFc5Gz5qF172GQhK5HpDbWs8F6qcSxdHn5XqAstf1fY"); + + + public static final String LOCAL_RPC_URL = "http://127.0.0.1:8899"; + public static final String LOCAL_ANDROID_TEST_RPC_URL = "http://10.0.2.2:8899"; + public static final String TESTNET_RPC_URL = "https://api.testnet.solana.com"; + public static final String DEVNET_RPC_URL = "https://api.devnet.solana.com"; + + // RPC URL для используемой ноды Solana + public static String RPC_URL = DEVNET_RPC_URL; + // Запись для хранения ключей +// public record KeyPair(String name, String publicKey, String privateKey) {} не надо больше + + // Массив пар ключей + public static final KeyPair[] KEYS = { + new KeyPair("key1", "HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA", // есть в дев нет!!! --url https://api.devnet.solana.com + "5pbFo9Zq1VsNheHwbEp6AZKa6R62CZHoGkJFZnugpMEtCmkQFjuUP7TgA5hSPqv4NABGmPP62qVnDPHmRqEAwvJc"), + new KeyPair("key2", "E3ZDHbWv1qiFvDTmaRc9wjFCgbQw6UmKJLJYbaTNvjAh", + "5qm1GJGXB1fFJ3YsU5Y3XXgTiQfaimqBWk79oEveFASH9D2of3jqUoT7dumBvS449fW5j5Sw8MgAMH2QBMmFPdry"), + new KeyPair("key3", "6bFc5Gz5qF172GQhK5HpDbWs8F6qcSxdHn5XqAstf1fY", + "3VYfYZZ3ugmgwisiQQAfcimX9T65AE9BmwmYVixAUj4jyneccSE9rzbC3g5twvH7ECZ8xgp7emJo3pR4yQqCwjGn") + }; + + // Метод для определения ключа + public static String identifyKey(String key) { + for (KeyPair kp : KEYS) { + if (kp.getPublicKey().equals(key)) { + return kp.getName() + "(public)"; + } + if (kp.getPrivateKey().equals(key)) { + return kp.getName() + "(private)"; + } + } + return key; // если не найдено + } + + // Метод для получения KeyPair по имени + public static KeyPair getKeyByName(String name) { + for (KeyPair kp : KEYS) { + if (kp.getName().equals(name)) { + return kp; + } + } + return null; // если не найдено + } + + // Метод форматирования лампортов в SOL + public static String lamportsToSol(long lamports) { + double sol = lamports / 1_000_000_000.0; + DecimalFormat df = new DecimalFormat("0.00000000"); + return df.format(sol); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/ExeptionList.txt b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/ExeptionList.txt new file mode 100644 index 0000000..f23c3a0 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/ExeptionList.txt @@ -0,0 +1,35 @@ + +Exeption - если что то полетело в коде + +SolanaRpcConnectionException - Не удалось подключиться к RPC Solana или получить ответ + +SolanaLibLogicException - Базовое исключение всех ошибок, связанных с Solana + Выкидываем во всех не стандартных случаях из библиотеки вместо стандартного Exception + +SolanaProgramException - Исключение, выбрасываемое при кастомной ошибке от Solana-программы (смарт контракта). Например: "custom program error: 0x1771" + +SolanaInsufficientFundsForFeeException - Недостаточно SOL для оплаты комиссии (InsufficientFundsForFee). + это если вызвали регистрацию без средств + (но получается тоже не надо так как - прога не вызовет её без проверки баланса) + + + + +нет такого пользователя + + + + + + + + + + + + + + + SolanaIncorrectProgramIdException Неверный programId — вызывается не та программа (IncorrectProgramId) +возможно надо что бы быстро находить новый програм Ид +(но по факту он не меняется если кто то не потеряет пароль!!! ) ну или потребуется один раз при переходе на DAO \ No newline at end of file diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaErrorHandler.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaErrorHandler.java new file mode 100644 index 0000000..e53c095 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaErrorHandler.java @@ -0,0 +1,43 @@ +package me.shineup.solana.exceptions; + + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class SolanaErrorHandler { + + public static void handleRpcJsonError(String json) throws SolanaException { + try { + JsonObject obj = JsonParser.parseString(json).getAsJsonObject(); + if (!obj.has("error")) return; + + JsonObject error = obj.getAsJsonObject("error"); + String msg = error.has("message") ? error.get("message").getAsString() : ""; + + handleSolanaError(msg); + + } catch (Exception e) { + // fallback + throw new SolanaException("Ошибка обработки RPC-ошибки", e); + } + } + + public static void handleSolanaError(String errorMessage) throws SolanaException { + if (errorMessage == null || errorMessage.isEmpty()) return; + + if (errorMessage.contains("custom program error: 0x")) { + String hex = errorMessage.substring(errorMessage.indexOf("0x")).split(" ")[0]; + throw new SolanaException_InProgram(hex); + } + + if (errorMessage.contains("InsufficientFundsForFee")) { + throw new SolanaException_InsufficientFundsForFee(); + } + + if (errorMessage.contains("IncorrectProgramId")) { + throw new SolanaException_IncorrectProgramId(); + } + + throw new SolanaException("Неизвестная ошибка Solana: " + errorMessage); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException.java new file mode 100644 index 0000000..b054ba4 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException.java @@ -0,0 +1,13 @@ +package me.shineup.solana.exceptions; + + +/** Базовое исключение всех ошибок, связанных с Solana */ +public class SolanaException extends Exception { + public SolanaException(String message) { + super(message); + } + + public SolanaException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InProgram.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InProgram.java new file mode 100644 index 0000000..4367d56 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InProgram.java @@ -0,0 +1,41 @@ +package me.shineup.solana.exceptions; + +/** + * Исключение, выбрасываемое при кастомной ошибке от Solana-программы. + * Например: "custom program error: 0x1771" или 10001 + */ +public class SolanaException_InProgram extends SolanaException { + private final int errorCode; + + /** + * Создаёт исключение на основе шестнадцатеричного кода (например, "0x1771"). + */ + public SolanaException_InProgram(String errorCodeHex) { + super("Ошибка от смарт-контракта. Код: " + parseHex(errorCodeHex)); + this.errorCode = parseHex(errorCodeHex); + } + + /** + * Создаёт исключение на основе десятичного кода (например, 10001). + */ + public SolanaException_InProgram(int errorCodeDecimal) { + super("Ошибка от смарт-контракта. Код: " + errorCodeDecimal); + this.errorCode = errorCodeDecimal; + } + + public int getErrorCodeDecimal() { + return errorCode; + } + + public String getErrorCodeHex() { + return "0x" + Integer.toHexString(errorCode); + } + + private static int parseHex(String hex) { + try { + return Integer.parseInt(hex.replace("0x", ""), 16); + } catch (NumberFormatException e) { + return -1; + } + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_IncorrectProgramId.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_IncorrectProgramId.java new file mode 100644 index 0000000..4f4c6ad --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_IncorrectProgramId.java @@ -0,0 +1,12 @@ +package me.shineup.solana.exceptions; + +/** + * Неверный programId — вызывается не та программа (IncorrectProgramId). + */ +public class SolanaException_IncorrectProgramId extends SolanaException { + public SolanaException_IncorrectProgramId() { + super("Указан неверный programId — не соответствует контракту"); + } +} + + diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InsufficientFundsForFee.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InsufficientFundsForFee.java new file mode 100644 index 0000000..64f10ee --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_InsufficientFundsForFee.java @@ -0,0 +1,10 @@ +package me.shineup.solana.exceptions; + +/** + * Недостаточно SOL для оплаты комиссии (InsufficientFundsForFee). + */ +public class SolanaException_InsufficientFundsForFee extends SolanaException { + public SolanaException_InsufficientFundsForFee() { + super("Недостаточно средств на балансе для оплаты комиссии (InsufficientFundsForFee)"); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_LibLogic.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_LibLogic.java new file mode 100644 index 0000000..2680816 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_LibLogic.java @@ -0,0 +1,21 @@ +package me.shineup.solana.exceptions; + +/** + * Исключение, выбрасываемое вручную при логических проверках в библиотеке. + * К сообщению автоматически добавляется строка вызова (класс и номер строки). + */ +public class SolanaException_LibLogic extends SolanaException { + + public SolanaException_LibLogic(String userMessage) { + super(userMessage + getSourceSuffix()); + } + + private static String getSourceSuffix() { + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + if (stack.length > 3) { + StackTraceElement caller = stack[3]; + return " (исходный код: " + caller.getFileName() + ":" + caller.getLineNumber() + ")"; + } + return ""; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_RpcConnection.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_RpcConnection.java new file mode 100644 index 0000000..73e7ff2 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_RpcConnection.java @@ -0,0 +1,8 @@ +package me.shineup.solana.exceptions; + +/** Не удалось подключиться к RPC или получить ответ */ +public class SolanaException_RpcConnection extends SolanaException { + public SolanaException_RpcConnection(String message) { + super(message); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_UserNotFound.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_UserNotFound.java new file mode 100644 index 0000000..04bf799 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/exceptions/SolanaException_UserNotFound.java @@ -0,0 +1,14 @@ +package me.shineup.solana.exceptions; + +/** + * Пользователь с указанным идентификатором не найден в системе. + */ +public class SolanaException_UserNotFound extends SolanaException { + public SolanaException_UserNotFound() { + super("Пользователь не найден в системе."); + } + + public SolanaException_UserNotFound(String msg) { + super("Пользователь не найден в системе: " + msg); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/InitializeUserCounter/InitializeUserCounter.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/InitializeUserCounter/InitializeUserCounter.java new file mode 100644 index 0000000..677fa0e --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/InitializeUserCounter/InitializeUserCounter.java @@ -0,0 +1,98 @@ +package me.shineup.solana.internal.callSolanaFunc.InitializeUserCounter; + + +import org.p2p.solanaj.core.AccountMeta; +import org.p2p.solanaj.core.PublicKey; +import org.p2p.solanaj.programs.SystemProgram; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.internal.utils.resultChecker.ResultChecker; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.SolanaProgramCaller; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Вызывает Anchor-функцию `initialize_user_counter` смарт-контракта на Solana. + * + * Эта функция предназначена для одноразовой инициализации PDA-аккаунта, в котором будет храниться + * счётчик пользователей. Аккаунт создаётся с сидом "user_counter" и содержит 8 байт, представляющих число. + * + * Повторный вызов приведёт к ошибке (если PDA уже существует). + * + */ + +public class InitializeUserCounter { + + private static final Logger LOG = LoggerFactory.getLogger(InitializeUserCounter.class); + +/** + * Вызывает Anchor-функцию `initialize_user_counter` смарт-контракта на Solana. + * + * Эта функция предназначена для одноразовой инициализации PDA-аккаунта, в котором будет храниться + * счётчик пользователей. Аккаунт создаётся с сидом "user_counter" и содержит 8 байт, представляющих число. + * Вызвать её в принципе может кто угодно, кто оплатит создание этого пда + * + * После того как PDA будет создан, любой повторный вызов приведёт к ошибке (если PDA уже существует). + */ + public static String callInitializeUserCounter( + String publicKeyB58, + String privateKeyB58 + ) { + try { + // ───────────────────────────────────────────────────────────── + // 1. Генерируем PDA-адрес для сидов ["user_counter"] + // ───────────────────────────────────────────────────────────── + String seed = "user_counter"; + PublicKey counterPda = PublicKey.findProgramAddress( + Collections.singletonList(seed.getBytes(StandardCharsets.UTF_8)), + Const.PROGRAM_ID_key + ).getAddress(); + + // ───────────────────────────────────────────────────────────── + // 2. Аргументы Anchor-функции: initialize_user_counter не требует входных данных + // ───────────────────────────────────────────────────────────── + byte[] serializedArgs = new byte[0]; // нет параметров + + // ───────────────────────────────────────────────────────────── + // 3. Список аккаунтов + // ───────────────────────────────────────────────────────────── + List accounts = Arrays.asList( + new AccountMeta(new PublicKey(publicKeyB58), true, true), // payer / signer + new AccountMeta(counterPda, false, true), // pda: user_counter + new AccountMeta(SystemProgram.PROGRAM_ID, false, false) // system_program + ); + + // ───────────────────────────────────────────────────────────── + // 4. Вызов Anchor-функции + // ───────────────────────────────────────────────────────────── + return SolanaProgramCaller.callAnchorFunction( + publicKeyB58, + privateKeyB58, + "initialize_user_counter", // имя функции Anchor + Const.PROGRAM_ID_key, + accounts, + serializedArgs + ); + + } catch (Exception e) { + LOG.error("❌ Ошибка вызова initialize_user_counter", e); + return null; + } + } + + + // Для теста + public static void main(String[] args) { +// Const.RPC_URL=Const.DEVNET_RPC_URL; + String sig = InitializeUserCounter.callInitializeUserCounter( + Const.getKeyByName("key1").getPublicKey(), + Const.getKeyByName("key1").getPrivateKey() + ); + ResultChecker.check(sig); + } +} + diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserStepOne.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserStepOne.java new file mode 100644 index 0000000..c2bef03 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserStepOne.java @@ -0,0 +1,104 @@ +package me.shineup.solana.internal.callSolanaFunc.RegisterUser; + +import org.p2p.solanaj.core.AccountMeta; +import org.p2p.solanaj.core.PublicKey; +import org.p2p.solanaj.programs.SystemProgram; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.internal.utils.resultChecker.ResultChecker; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.SolanaProgramCaller; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Вызывает Anchor-функцию `register_user_step_one`. !!!!!!!!! ЭТО УСТАРЕЛО И БОЛЬШЕ НЕ НАДО + * + * Функция создаёт нового пользователя: + * - проверяет логин, + * - создаёт PDA-аккаунт пользователя, + * - переводит 0.01 SOL на счёт администрации, + * - сохраняет логин, ID, pubkey и статус 0 в PDA, + * - обновляет счётчик пользователей. + */ + + +public class RegisterUserStepOne { + + private static final Logger LOG = LoggerFactory.getLogger(RegisterUserStepOne.class); + + public static String callRegisterUserStepOne( + String payerPubkeyB58, + String payerPrivkeyB58, + String login, + String userPubkeyB58 + ) { + try { + // 1. Адрес получателя комиссии + PublicKey feeReceiver = Const.ADMIN_FEE_ACCOUNT; + + // 2. PDA-адрес по логину: seed = "u=" + login + String seed = Const.userSeedsPrefix + login; + PublicKey userPda = PublicKey.findProgramAddress( + Collections.singletonList(seed.getBytes(StandardCharsets.UTF_8)), + Const.PROGRAM_ID_key + ).getAddress(); + + // 3. Адрес PDA счётчика пользователей + String counterSeed = Const.USER_COUNTER_SEED; + PublicKey counterPda = PublicKey.findProgramAddress( + Collections.singletonList(counterSeed.getBytes(StandardCharsets.UTF_8)), + Const.PROGRAM_ID_key + ).getAddress(); + + // 4. Сериализация аргументов Anchor + byte[] loginBytes = login.getBytes(StandardCharsets.UTF_8); + byte[] userPubkeyBytes = new PublicKey(userPubkeyB58).toByteArray(); + + byte[] serializedArgs = SolanaProgramCaller.encodeAnchorArgs( + Arrays.asList("string", "pubkey"), + Arrays.asList(loginBytes, userPubkeyBytes) + ); + + // 5. Аккаунты, требуемые для вызова + List accounts = Arrays.asList( + new AccountMeta(new PublicKey(payerPubkeyB58), true, true), // signer + new AccountMeta(counterPda, false, true), // user_counter + new AccountMeta(userPda, false, true), // user_by_login_pda + new AccountMeta(SystemProgram.PROGRAM_ID, false, false), // system_program + new AccountMeta(feeReceiver, false, true) // fee_receiver + ); + + // 6. Вызов Anchor-функции + return SolanaProgramCaller.callAnchorFunction( + payerPubkeyB58, + payerPrivkeyB58, + "register_user_step_one", + Const.PROGRAM_ID_key, + accounts, + serializedArgs + ); + + } catch (Exception e) { + LOG.error("❌ Ошибка вызова register_user_step_one", e); + return null; + } + } + + // Для теста + public static void main(String[] args) { + Const.RPC_URL = Const.LOCAL_RPC_URL; + + String sig = RegisterUserStepOne.callRegisterUserStepOne( + Const.getKeyByName("key1").getPublicKey(), // кто платит + Const.getKeyByName("key1").getPrivateKey(), // + "testlogin", // логин пользователя + Const.getKeyByName("key2").getPublicKey() // публичный ключ пользователя + ); + ResultChecker.check(sig); + } + +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserWithOneDev.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserWithOneDev.java new file mode 100644 index 0000000..4d4ec4b --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/callSolanaFunc/RegisterUser/RegisterUserWithOneDev.java @@ -0,0 +1,156 @@ +package me.shineup.solana.internal.callSolanaFunc.RegisterUser; + +import me.shineup.solana.SolanaWrapper; +import me.shineup.solana.internal.readFromSolana.userCounter.UserCounterReader; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.standartActions.keysGenerator.KeyPairBase58; +import me.shineup.solana.internal.utils.SolanaProgramCaller; +import me.shineup.solana.internal.utils.resultChecker.ResultChecker; +import org.p2p.solanaj.core.AccountMeta; +import org.p2p.solanaj.core.PublicKey; +import org.p2p.solanaj.programs.SystemProgram; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static me.shineup.solana.internal.standartActions.keysGenerator.SolanaKeyGeneratorManual.generateKeyPair; + +/** + * Вызывает Anchor-функцию `register_user_with_one_dev`. + * + * Выполняет регистрацию пользователя и одного устройства. + */ +public class RegisterUserWithOneDev { + + private static final Logger LOG = LoggerFactory.getLogger(RegisterUserWithOneDev.class); + + // Пример вызова + public static void main(String[] args) { +// Const.RPC_URL = Const.LOCAL_RPC_URL; + Const.RPC_URL=Const.DEVNET_RPC_URL; + try { + String publicKey = "2fppzT84GoDqQe2RCxuK2gjZUrMhkzKgVTY6BzfLF9RX"; + String privateKey = "2qTERJQ2EBPsHWNXxhAWW4pBk1beo1BWtifCPsDbrDhw9z5riNLsUUj6BNQ9UbprJq398Zk3Fv21ZGUjRrAU4T73"; + SolanaWrapper.getBalance(Const.getKeyByName("key1").publicKey); +// SolanaWrapper.sendSol(Const.getKeyByName("key1").getPrivateKey(),publicKey, 1000000); + SolanaWrapper.getBalance(publicKey); +// KeyPairBase58 keys = generateKeyPair(); + String sig = RegisterUserWithOneDev.callRegisterUserWithOneDev( + Const.getKeyByName("key1").getPublicKey(), // payer + Const.getKeyByName("key1").getPrivateKey(), // + "testlogin", // логин + Const.getKeyByName("key2").getPublicKey(), // подпись устройства + Const.getKeyByName("key2").getPublicKey() // x25519 + ); + ResultChecker.check(sig); + } catch (Exception e) { + LOG.error(e.getMessage()); + } + + + } + + + public static String callRegisterUserWithOneDev( + String payerPubkeyB58, + String payerPrivkeyB58, + String login, +// String userPubkeyB58, пока userPubkeyB58=payerPubkeyB58 + String deviceSignPubkeyB58, + String deviceX25519PubkeyB58 + ) throws Exception { + + // Адреса + PublicKey payer = new PublicKey(payerPubkeyB58); +/** PublicKey userPub = new PublicKey(userPubkeyB58); + * тут в принципе можно передавать на смарт контракт разные параметры + * и получиться что платит один а создаёт аккаунт на другое имя + * это может актуально при расширении, если дописать додумать и т.д. + * но пока это отключено и кто оплатил тна того и оформляем аккаунт + * пока так работает только за себя и можно отпраавлять транзакции + */ + PublicKey userPub = new PublicKey(payerPubkeyB58); // пока тот кто подписал транзакцию, на него же и аккаунт создаём + + + PublicKey devSignPub = new PublicKey(deviceSignPubkeyB58); + PublicKey devX25519Pub = new PublicKey(deviceX25519PubkeyB58); + + // Читаем текущий ID + long currentId = UserCounterReader.getUserCount(); + long newId = currentId + 1; + + // Счётчик пользователей + + PublicKey counterPda = PublicKey.findProgramAddress( + Arrays.asList("user_counter".getBytes(StandardCharsets.UTF_8)), + Const.PROGRAM_ID_key + ).getAddress(); + + // PDA по логину: ["login=", login] + PublicKey loginPda = PublicKey.findProgramAddress( + Arrays.asList( + "login=".getBytes(StandardCharsets.UTF_8), + login.getBytes(StandardCharsets.UTF_8) + ), + Const.PROGRAM_ID_key + ).getAddress(); + + // 5 возможных PDA по ID: ["userId=", String.valueOf(newId)] + String idSeedStr = String.valueOf(newId); + List idCandidates = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + byte[] prefix = "userId=".getBytes(StandardCharsets.UTF_8); + byte[] id = idSeedStr.getBytes(StandardCharsets.UTF_8); + byte[] seed1 = prefix; + byte[] seed2 = id; + PublicKey pda = PublicKey.findProgramAddress(Arrays.asList(seed1, seed2), Const.PROGRAM_ID_key).getAddress(); + idCandidates.add(pda); + } + + // Комиссионный адрес + PublicKey feeReceiver = Const.ADMIN_FEE_ACCOUNT; + + // Аргументы Anchor + byte[] loginBytes = login.getBytes(StandardCharsets.UTF_8); + byte[] pubkeyBytes = userPub.toByteArray(); + byte[] devSignBytes = devSignPub.toByteArray(); + byte[] devX25519Bytes = devX25519Pub.toByteArray(); + + byte[] serializedArgs = SolanaProgramCaller.encodeAnchorArgs( + Arrays.asList("string", "pubkey", "pubkey", "pubkey"), + Arrays.asList(loginBytes, pubkeyBytes, devSignBytes, devX25519Bytes) + ); + + // Список аккаунтов + List accounts = new ArrayList(); + accounts.add(new AccountMeta(payer, true, true)); + accounts.add(new AccountMeta(counterPda, false, true)); + accounts.add(new AccountMeta(loginPda, false, true)); + + for (PublicKey idPda : idCandidates) { + accounts.add(new AccountMeta(idPda, false, true)); + } + + accounts.add(new AccountMeta(SystemProgram.PROGRAM_ID, false, false)); + accounts.add(new AccountMeta(feeReceiver, false, true)); + + // Вызов Anchor-функции + return SolanaProgramCaller.callAnchorFunction( + payerPubkeyB58, + payerPrivkeyB58, + "register_user_with_one_dev", + Const.PROGRAM_ID_key, + accounts, + serializedArgs + ); + + } + +} + + + diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdParser.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdParser.java new file mode 100644 index 0000000..6a06e9d --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdParser.java @@ -0,0 +1,103 @@ +package me.shineup.solana.internal.readFromSolana.userById; + +import me.shineup.solana.exceptions.SolanaException; +import me.shineup.solana.model.UserById; +import org.bitcoinj.core.Base58; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * Десериализует сырые байты из PDA в объект {@link UserById}. + * + * Сейчас поддерживается только формат 1, но общий метод + * parse(...) готов к расширению версий. + */ +class UserByIdParser { + + /** Точка входа: определяем формат по первым 4 байтам (LE u32). */ + public static UserById parse(byte[] data) throws Exception { + if (data.length < 4) + throw new SolanaException("Недостаточно данных для чтения format_type"); + + int fmt = ByteBuffer.wrap(data, 0, 4) + .order(ByteOrder.LITTLE_ENDIAN) + .getInt(); + + switch (fmt) { + case 1: + return parseFormat1(data); + default: + throw new SolanaException("Неподдерживаемый формат: " + fmt); + } + } + + /** + * Формат 1 (см. Rust-комментарии): + * [0..4] format + * [4..12] id (u64 LE) + * [12] len(login) u8 + * [13..] login + * [...] pubkey 32 байта + * [...] deviceCount u8 + * [...] devices ×65 байт (type + 32 + 32) + */ + private static UserById parseFormat1(byte[] data) throws Exception { + int offset = 4; + + // id + if (data.length < offset + 8) throw new Exception("Мало байт для id"); + long id = ByteBuffer.wrap(data, offset, 8) + .order(ByteOrder.LITTLE_ENDIAN).getLong(); + offset += 8; + + // login + int loginLen = data[offset] & 0xFF; + offset += 1; + if (data.length < offset + loginLen) throw new Exception("Мало байт для login"); + String login = new String(data, offset, loginLen, StandardCharsets.UTF_8); + offset += loginLen; + + // pubkey + if (data.length < offset + 32) throw new Exception("Мало байт для pubkey"); + byte[] pubkeyBytes = new byte[32]; + System.arraycopy(data, offset, pubkeyBytes, 0, 32); + String pubkey58 = Base58.encode(pubkeyBytes); + offset += 32; + + // deviceCount + if (data.length < offset + 1) throw new Exception("Мало байт для deviceCount"); + int devCount = data[offset] & 0xFF; + offset += 1; + + // devices + List devices = new ArrayList<>(); + for (int i = 0; i < devCount; i++) { + if (data.length < offset + 65) + throw new Exception("Мало байт для devices[" + i + "]"); + UserById.DeviceInfo d = new UserById.DeviceInfo(); + d.deviceType = data[offset] & 0xFF; + byte[] devPub = new byte[32]; + byte[] x25519 = new byte[32]; + System.arraycopy(data, offset + 1, devPub, 0, 32); + System.arraycopy(data, offset + 33, x25519, 0, 32); + d.devicePubkey = Base58.encode(devPub); + d.x25519Pubkey = Base58.encode(x25519); + devices.add(d); + offset += 65; + } + + // собираем объект + UserById u = new UserById(); + u.format = 1; + u.id = id; + u.login = login; + u.pubkey = pubkey58; + u.deviceCount = devCount; + u.devices = devices; + return u; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdReader.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdReader.java new file mode 100644 index 0000000..67d5a26 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userById/UserByIdReader.java @@ -0,0 +1,48 @@ +package me.shineup.solana.internal.readFromSolana.userById; + +import me.shineup.solana.exceptions.SolanaException_UserNotFound; +import me.shineup.solana.model.UserById; +import me.shineup.solana.internal.utils.reader.PdaReader; +import me.shineup.solana.config.Const; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; + +/** + * Читает из PDA данные пользователя по числовому ID + * и десериализует их в {@link UserById}. + */ +public class UserByIdReader { + + private static final Logger LOG = LoggerFactory.getLogger(UserByIdReader.class); + + /** Получить UserById по ID. */ + public static UserById getUserById(long id) throws Exception{ + byte[] seed1 = "userId=".getBytes(StandardCharsets.UTF_8); + byte[] seed2 = Long.toString(id).getBytes(StandardCharsets.UTF_8); + String programId = Const.PROGRAM_ID_str; + + byte[] data = PdaReader.readTwoSeeds(seed1, seed2, programId); + + if (data == null) { + LOG.warn("⚠️ Нет данных в PDA для id={}", id); + throw new SolanaException_UserNotFound(); + } + + return UserByIdParser.parse(data); // Передаём данные в парсер + } + + /** Быстрый тест чтения. */ + public static void main(String[] args) { + long id = 10; // поменять на существующий ID + try { + UserById u = UserByIdReader.getUserById(id); + System.out.println("✅ Найден: " + u); + } catch (SolanaException_UserNotFound e) { + System.out.println("⚠️ Пользователь с id=" + id + " не найден"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginParser.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginParser.java new file mode 100644 index 0000000..9c20a74 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginParser.java @@ -0,0 +1,73 @@ +package me.shineup.solana.internal.readFromSolana.userByLogin; + + +import me.shineup.solana.model.UserByLogin; + +/** + * Парсер для десериализации массива байт в объект UserByLogin. + * Поддерживает несколько форматов, определяемых по первым 4 байтам (LE u32). + */ +class UserByLoginParser { + + /** + * Основной метод: определяет формат по первым 4 байтам, вызывает нужный парсер. + * @param data байты, полученные из PDA + * @return объект UserByLogin + * @throws Exception если формат неизвестен или ошибка разбора + */ + public static UserByLogin parse(byte[] data) throws Exception { + if (data.length < 4) throw new Exception("Недостаточно данных для чтения format_type"); + + int format = java.nio.ByteBuffer.wrap(data, 0, 4) + .order(java.nio.ByteOrder.LITTLE_ENDIAN).getInt(); + + switch (format) { + case 1: + return parseFormat1(data); + default: + throw new Exception("Неподдерживаемый формат данных: " + format); + } + } + + /** + * Парсит формат 1: + * [0..4] — формат + * [4] — длина логина (u8) + * [5..X] — логин + * [X..X+8] — id (u64 LE) + * [X..X+32] — pubkey (32 байта) + * [X+32..X+36] — status (u32 LE) + */ + public static UserByLogin parseFormat1(byte[] data) throws Exception { + int offset = 4; // после format_type + + int loginLen = data[offset] & 0xFF; + offset += 1; + + if (data.length < offset + loginLen + 8 + 32 + 4) + throw new Exception("Недостаточно байт для парсинга format 1"); + + String login = new String(data, offset, loginLen, java.nio.charset.StandardCharsets.UTF_8); + offset += loginLen; + + long id = java.nio.ByteBuffer.wrap(data, offset, 8) + .order(java.nio.ByteOrder.LITTLE_ENDIAN).getLong(); + offset += 8; + + byte[] pubkeyBytes = new byte[32]; + System.arraycopy(data, offset, pubkeyBytes, 0, 32); + String pubkey = org.bitcoinj.core.Base58.encode(pubkeyBytes); + offset += 32; + + int status = java.nio.ByteBuffer.wrap(data, offset, 4) + .order(java.nio.ByteOrder.LITTLE_ENDIAN).getInt(); + + UserByLogin result = new UserByLogin(); + result.format = 1; + result.login = login; + result.id = id; + result.pubkey = pubkey; + result.status = status; + return result; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginReader.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginReader.java new file mode 100644 index 0000000..ff227e4 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userByLogin/UserByLoginReader.java @@ -0,0 +1,58 @@ +package me.shineup.solana.internal.readFromSolana.userByLogin; + + +import me.shineup.solana.exceptions.SolanaException_UserNotFound; +import me.shineup.solana.model.UserByLogin; +import me.shineup.solana.internal.utils.reader.PdaReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; + +import java.nio.charset.StandardCharsets; + +/** + * Класс для получения объекта UserByLogin по логину из PDA + */ +public class UserByLoginReader { + + private static final Logger LOG = LoggerFactory.getLogger(UserByLoginReader.class); + + /** + * Получает объект UserByLogin по логину + * @param login Логин пользователя (например, "sol_user") + * @return Объект UserByLogin или null, если данных нет + * @throws Exception если ошибка соединения или парсинга + */ + public static UserByLogin getUserByLogin(String login) throws Exception { + byte[] seed1 = "login=".getBytes(StandardCharsets.UTF_8); + byte[] seed2 = login.getBytes(StandardCharsets.UTF_8); + String programId = Const.PROGRAM_ID_str; + + byte[] data = PdaReader.readTwoSeeds(seed1, seed2, programId); + + if (data == null) { + LOG.warn("⚠️ Нет данных в PDA для логина '{}'", login); + throw new SolanaException_UserNotFound(); + } + + // Передаём данные в парсер + return UserByLoginParser.parse(data); + } + + /** + * Тестовый запуск чтения информации о пользователе + */ + public static void main(String[] args) { + String login = "testlogin3"; // замените на нужный логин + try { + UserByLogin user = UserByLoginReader.getUserByLogin(login); + System.out.println("✅ Найден пользователь: " + login); + } catch (SolanaException_UserNotFound e) { + System.out.println("⚠️ Пользователь с id=" + login + " не найден"); + } catch (Exception e) { + System.err.println("❌ Ошибка при получении информации о пользователе: " + e.getMessage()); + e.printStackTrace(); + } + } +} + diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userCounter/UserCounterReader.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userCounter/UserCounterReader.java new file mode 100644 index 0000000..addb2a6 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/readFromSolana/userCounter/UserCounterReader.java @@ -0,0 +1,60 @@ +package me.shineup.solana.internal.readFromSolana.userCounter; + + + +import me.shineup.solana.exceptions.SolanaException; +import me.shineup.solana.internal.utils.reader.PdaReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Утилита для получения значения счётчика пользователей из PDA. + */ +public class UserCounterReader { + + private static final Logger LOG = LoggerFactory.getLogger(UserCounterReader.class); + + /** + * Считывает текущее количество пользователей из PDA "user_counter". + * + * @return количество пользователей (long), либо -1 если нет данных + * @throws Exception при ошибке подключения или чтения + */ + public static long getUserCount() throws Exception { + String seed = "user_counter"; + String programId = Const.PROGRAM_ID_str; + + byte[] data = PdaReader.readOneSeed(seed, programId); + if (data == null || data.length < 8) { + throw new SolanaException("⚠️ Не удалось прочитать счётчик пользователей — PDA пуст или слишком короткий"); // этого не должно случаться + } + + // Считываем первые 8 байт как u64 (Little Endian) + ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); + long count = buffer.getLong(); + + LOG.debug("👥 На данный момент в системе зарегистрировано: {} пользователей", count); + return count; + } + + /** + * Тестовый запуск + */ + public static void main(String[] args) { + try { + long count = getUserCount(); + if (count >= 0) { + System.out.println("✅ 👥 Количество пользователей системы на данный момент: " + count); + } else { + System.out.println("⚠️ Счётчик не найден или пуст"); + } + } catch (Exception e) { + System.err.println("❌ Ошибка при чтении счётчика пользователей: " + e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/airDrops/SolanaAirdrop.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/airDrops/SolanaAirdrop.java new file mode 100644 index 0000000..22bb9e5 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/airDrops/SolanaAirdrop.java @@ -0,0 +1,68 @@ +package me.shineup.solana.internal.standartActions.airDrops; + + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.shineup.solana.exceptions.SolanaException_LibLogic; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.SolanaRpcClient; + + +public class SolanaAirdrop { + private static final Logger log = LoggerFactory.getLogger(SolanaAirdrop.class); + + + // + public static void main(String[] args) { + + // Кол-во лампортов (1 SOL = 1_000_000_000 лампортов) + long lamports = 1_000_000_000L; + try { + + // Вызываем airdrop + String trx = SolanaAirdrop.requestAirdrop(Const.getKeyByName("key1").getPublicKey(), lamports); + + + // Вывод результата + log.info("Баланс должен скоро обновиться. " + trx); + } catch (Exception e) { + log.error("Airdrop не удался." + e.getMessage()); + } + } + + /** запрашивает AirDrop на счёт */ + public static String requestAirdrop(String publicKey, long lamports) throws Exception{ +// String requestJson = """ +// { +// "jsonrpc": "2.0", +// "id": 1, +// "method": "requestAirdrop", +// "params": ["%s", %d] +// } +// """.formatted(publicKey, lamports); + + String requestJson = String.format( + "{\n" + + " \"jsonrpc\": \"2.0\",\n" + + " \"id\": 1,\n" + + " \"method\": \"requestAirdrop\",\n" + + " \"params\": [\"%s\", %d]\n" + + "}", publicKey, lamports); + + + String response = SolanaRpcClient.getInstance().sendRequest(requestJson); + + JsonObject json = JsonParser.parseString(response).getAsJsonObject(); + + if (json.has("result")) { + String txSignature = json.get("result").getAsString(); + log.info("✅ Airdrop успешно запрошен. Tx: " + txSignature); + return txSignature; + } + throw new SolanaException_LibLogic("Неизвестный ответ: " + response); + } + + +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/balanse/SolanaBalanceChecker.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/balanse/SolanaBalanceChecker.java new file mode 100644 index 0000000..31d2c0b --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/balanse/SolanaBalanceChecker.java @@ -0,0 +1,72 @@ +package me.shineup.solana.internal.standartActions.balanse; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.SolanaRpcClient; + +public class SolanaBalanceChecker { + + // для теста + public static void main(String[] args) { + try { + +// Const.RPC_URL = Const.LOCAL_RPC_URL; + Const.RPC_URL = "https://api.devnet.solana.com"; + //Long balance1 = SolanaBalanceChecker.getBalance(Const.getKeyByName("key1").getPublicKey()); + Long balance1 = SolanaBalanceChecker.getBalance("HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA"); + Long balance2 = SolanaBalanceChecker.getBalance(Const.getKeyByName("key2").getPublicKey()); + Long balance3 = SolanaBalanceChecker.getBalance(Const.getKeyByName("key3").getPublicKey()); + } catch (Exception e) { + log.error( e.getMessage()); + } + } + + private static final Logger log = LoggerFactory.getLogger(SolanaBalanceChecker.class); + private final Gson gson = new Gson(); + + /** показывает баланс счёта */ + public static long getBalance(String publicKey) throws Exception { + + String requestJson = String.format( + "{\n" + + " \"jsonrpc\": \"2.0\",\n" + + " \"id\": 1,\n" + + " \"method\": \"getBalance\",\n" + + " \"params\": [\"%s\"]\n" + + "}", publicKey); +// try { + String responseJson = SolanaRpcClient.getInstance().sendRequest(requestJson); + + // Парсим строку JSON в дерево объектов + JsonObject root = JsonParser.parseString(responseJson).getAsJsonObject(); + +// if (root.has("error")) { +// log.error("❌ Не удалось получить баланс для " + publicKey); +// log.error("Ошибка от RPC: " + root.get("error")); +// new SolanaLibLogicException() ; +// } + + log.debug("📥 Ответ от RPC: " + responseJson); + + long balance = root.getAsJsonObject("result").get("value").getAsLong(); + double sol = balance / 1_000_000_000.0; + + log.info("✅ Баланс кошелька " + Const.identifyKey(publicKey) + ": " + Const.lamportsToSol(balance));// + " SOL или лампортов " + balance ); + + return balance; + +// } catch (Exception e) { +// log.error("❌ Не удалось получить баланс для " + publicKey); +// log.error("Ошибка при получении баланса: " + e.getMessage()); +// log.error("Ошибка при получении баланса: " + e.getStackTrace()[0] ); +// log.error("Ошибка при получении баланса: " + e.getStackTrace()[1] ); +// log.error("Ошибка при получении баланса: " + e.getStackTrace()[2] ); +// return -1; +// } + + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/KeyPairBase58.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/KeyPairBase58.java new file mode 100644 index 0000000..3eef7b4 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/KeyPairBase58.java @@ -0,0 +1,26 @@ +package me.shineup.solana.internal.standartActions.keysGenerator; + + + +/** + * Объект, представляющий пару ключей Solana в формате Base58: + * - публичный ключ (32 байта) + * - приватный ключ (64 байта, включает публичный) + */ +public class KeyPairBase58 { + public final String publicKey; + public final String privateKey; + + public KeyPairBase58(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + @Override + public String toString() { + return "KeyPairBase58{\n" + + " publicKey='" + publicKey + "',\n" + + " privateKey='" + privateKey + "'\n" + + '}'; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/SolanaKeyGeneratorManual.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/SolanaKeyGeneratorManual.java new file mode 100644 index 0000000..f9cdd46 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/keysGenerator/SolanaKeyGeneratorManual.java @@ -0,0 +1,101 @@ +package me.shineup.solana.internal.standartActions.keysGenerator; + + + +import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; +import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; +import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; +import org.bouncycastle.crypto.KeyGenerationParameters; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; + +import java.security.SecureRandom; + +public class SolanaKeyGeneratorManual { + + // ✅ Новый метод: возвращает пару ключей (в Base58) + public static KeyPairBase58 generateKeyPair() { + // Генератор ключей Ed25519 + Ed25519KeyPairGenerator keyGen = new Ed25519KeyPairGenerator(); + keyGen.init(new KeyGenerationParameters(new SecureRandom(), 256)); + AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); + + Ed25519PrivateKeyParameters privateKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); + Ed25519PublicKeyParameters publicKeyParams = (Ed25519PublicKeyParameters) keyPair.getPublic(); + + byte[] privateKey = privateKeyParams.getEncoded(); // 32 байта + byte[] publicKey = publicKeyParams.getEncoded(); // 32 байта + + byte[] solanaSecretKey = new byte[64]; + System.arraycopy(privateKey, 0, solanaSecretKey, 0, 32); + System.arraycopy(publicKey, 0, solanaSecretKey, 32, 32); + + return new KeyPairBase58( + Base58.encode(publicKey), + Base58.encode(solanaSecretKey) + ); + } + + + + public static void main(String[] args) { + KeyPairBase58 keys = generateKeyPair(); + + System.out.println("✅ Сгенерирован новый кошелёк Solana:"); + System.out.println("Публичный ключ (Base58): " + keys.publicKey); + System.out.println("Приватный ключ (Base58, 64 байта): " + keys.privateKey); + + System.out.println(); + System.out.println("String publicKey = \"" + keys.publicKey + "\";"); + System.out.println("String privateKey = \"" + keys.privateKey + "\";"); + } + +// +// // 👇 Встроенная реализация Base58 (без bitcoinj) + static class Base58 { + private static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); + private static final int BASE_58 = ALPHABET.length; + + public static String encode(byte[] input) { + if (input.length == 0) return ""; + + // Count leading zeros. + int zeros = 0; + while (zeros < input.length && input[zeros] == 0) { + ++zeros; + } + + // Convert base-256 digits to base-58 digits (plus conversion to ASCII characters) + int size = input.length * 2; + int[] encoded = new int[size]; + int length = 0; + + for (byte b : input) { + int carry = b & 0xFF; + int i = 0; + for (int j = size - 1; (carry != 0 || i < length) && j >= 0; j--, i++) { + carry += 256 * encoded[j]; + encoded[j] = carry % BASE_58; + carry /= BASE_58; + } + length = i; + } + + // Skip leading zeros in encoded. + int encodedStart = size - length; + while (encodedStart < size && encoded[encodedStart] == 0) { + encodedStart++; + } + + // Translate the result into a string. + StringBuilder result = new StringBuilder(zeros + size - encodedStart); + for (int i = 0; i < zeros; i++) { + result.append('1'); + } + for (int i = encodedStart; i < size; i++) { + result.append(ALPHABET[encoded[i]]); + } + + return result.toString(); + } + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/transfer/SolanaTransfer.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/transfer/SolanaTransfer.java new file mode 100644 index 0000000..0f1d738 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/standartActions/transfer/SolanaTransfer.java @@ -0,0 +1,73 @@ +package me.shineup.solana.internal.standartActions.transfer; + +import me.shineup.solana.exceptions.SolanaException_RpcConnection; +import me.shineup.solana.internal.standartActions.balanse.SolanaBalanceChecker; +import org.p2p.solanaj.core.Account; +import org.p2p.solanaj.core.PublicKey; +import org.p2p.solanaj.core.Transaction; +import org.p2p.solanaj.rpc.RpcClient; +import org.p2p.solanaj.rpc.RpcException; +import org.p2p.solanaj.programs.SystemProgram; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.KeyUtils; + +import static me.shineup.solana.internal.utils.SolanaProgramCaller.getLatestBlockhash; +import static me.shineup.solana.internal.utils.SolanaProgramCaller.sendTransactionWithBlockhash; + +public class SolanaTransfer { + private static final Logger log = LoggerFactory.getLogger(SolanaTransfer.class); + + public static void main(String[] args) { + try { + Const.RPC_URL = Const.LOCAL_RPC_URL; + SolanaBalanceChecker.getBalance(Const.getKeyByName("key1").getPublicKey()); + SolanaTransfer.sendSol(Const.getKeyByName("key1").getPrivateKey(), Const.getKeyByName("key2").getPublicKey(),100_000_000); + SolanaBalanceChecker.getBalance(Const.getKeyByName("key1").getPublicKey()); + SolanaBalanceChecker.getBalance(Const.getKeyByName("key2").getPublicKey()); + } catch (Exception e) { + log.error( e.getMessage()); + } + } + + + + /** + * Переводит lamports (1 SOL = 1_000_000_000 лампортов) + * @param fromBase58Secret - приватный ключ в виде массива из 64 байт + * @param toAddressBase58 - публичный ключ получателя + * @param lamports - сумма в лампортах + */ + public static String sendSol(String fromBase58Secret, String toAddressBase58, long lamports) throws Exception{ + try { + + RpcClient rpc = new RpcClient(Const.RPC_URL); + + byte[] senderSecretKey58 = KeyUtils.base58ToBytes(fromBase58Secret); + + // Загружаем отправителя + Account from = new Account(senderSecretKey58); + PublicKey to = new PublicKey(toAddressBase58); + + // Создаём транзакцию + Transaction transaction = new Transaction(); + transaction.addInstruction( + SystemProgram.transfer(from.getPublicKey(), to, lamports) + ); + + // Получаем blockhash + String recentBlockhash = getLatestBlockhash(rpc); + + // отправляем транзакцию + String signature = sendTransactionWithBlockhash(rpc, transaction, recentBlockhash, from); + + + log.info("✅ Перевод " + Const.lamportsToSol(lamports) + " отправлен с " + Const.identifyKey(fromBase58Secret) + " на " + Const.identifyKey(toAddressBase58) + " . Подпись: " + signature); + return signature; + } catch (RpcException e) { + throw new SolanaException_RpcConnection("❌ Ошибка RPC: " + e.getMessage()); + } + + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyPair.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyPair.java new file mode 100644 index 0000000..f47a04f --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyPair.java @@ -0,0 +1,55 @@ +package me.shineup.solana.internal.utils; + +public class KeyPair { + + public final String name; + public final String publicKey; + public final String privateKey; + + public KeyPair(String name, String publicKey, String privateKey) { + this.name = name; + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getName() { + return name; + } + + public String getPublicKey() { + return publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + @Override + public String toString() { + return "KeyPair{" + + "name='" + name + '\'' + + ", publicKey='" + publicKey + '\'' + + ", privateKey='" + privateKey + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + KeyPair keyPair = (KeyPair) o; + + if (!name.equals(keyPair.name)) return false; + if (!publicKey.equals(keyPair.publicKey)) return false; + return privateKey.equals(keyPair.privateKey); + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + publicKey.hashCode(); + result = 31 * result + privateKey.hashCode(); + return result; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyUtils.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyUtils.java new file mode 100644 index 0000000..15eaf54 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/KeyUtils.java @@ -0,0 +1,39 @@ +package me.shineup.solana.internal.utils; + + +import java.util.Arrays; + +public class KeyUtils { + + private static final String BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + + public static byte[] base58ToBytes(String base58) { + // Простейший декодер Base58 + int[] indexes = new int[128]; + Arrays.fill(indexes, -1); + for (int i = 0; i < BASE58_ALPHABET.length(); i++) { + indexes[BASE58_ALPHABET.charAt(i)] = i; + } + + byte[] input = new byte[base58.length()]; + for (int i = 0; i < base58.length(); i++) { + input[i] = (byte) indexes[base58.charAt(i)]; + } + + byte[] result = new byte[64]; // длина ключа + int length = 0; + + for (byte b : input) { + int carry = b & 0xFF; + int i = 0; + for (int j = result.length - 1; (carry != 0 || i < length) && j >= 0; j--, i++) { + carry += 58 * (result[j] & 0xFF); + result[j] = (byte) (carry % 256); + carry /= 256; + } + length = i; + } + + return result; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaProgramCaller.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaProgramCaller.java new file mode 100644 index 0000000..e8ac18f --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaProgramCaller.java @@ -0,0 +1,378 @@ +package me.shineup.solana.internal.utils; + +import me.shineup.solana.config.Const; +import me.shineup.solana.exceptions.SolanaException; +import me.shineup.solana.exceptions.SolanaException_InProgram; +import me.shineup.solana.exceptions.SolanaException_InsufficientFundsForFee; +import me.shineup.solana.exceptions.SolanaException_RpcConnection; +import org.bitcoinj.core.Base58; +import org.p2p.solanaj.core.*; +import org.p2p.solanaj.rpc.RpcClient; +import org.p2p.solanaj.rpc.RpcException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.*; + +import java.util.Map; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class SolanaProgramCaller { + + // Логгер для вывода отладочной информации + private static final Logger log = LoggerFactory.getLogger(SolanaProgramCaller.class); + + /** + * Универсальный метод вызова Anchor-функции на Solana. + * + * @param publicKeyB58 Публичный ключ вызывающего аккаунта в формате base58 + * @param privateKeyB58 Приватный ключ в формате base58 (только первые 32 байта или полный 64-байтный seed) + * @param functionName Имя функции Anchor (например: "register_user") + * @param programId Адрес Anchor-программы, в которую делается вызов + * @param accounts Список аккаунтов, необходимых для вызова (AccountMeta) + * @param serializedArgs Сериализованные аргументы вызова (без дискриминатора) + * @return base58-подпись транзакции или null при ошибке + */ + public static String callAnchorFunction( + String publicKeyB58, + String privateKeyB58, + String functionName, + PublicKey programId, + List accounts, + byte[] serializedArgs + ) throws Exception { + + // Создаём RPC клиент для взаимодействия с Solana (через URL, заданный в конфиге) + RpcClient rpc = new RpcClient(Const.RPC_URL); + + // Декодируем публичный ключ вызывающего аккаунта из Base58 строки + PublicKey pubKey = new PublicKey(publicKeyB58); + + // Декодируем приватный ключ из Base58 строки (ожидается 32 байта seed или 64 байта полного ключа) + byte[] priv = Base58.decode(privateKeyB58); + + // Если длина приватного ключа всего 32 байта (seed), то дополняем его 32 байтами публичного ключа + if (priv.length == 32) { + byte[] full = new byte[64]; // 64-байтный ключ для Ed25519 (32 priv + 32 pub) + System.arraycopy(priv, 0, full, 0, 32); // копируем 32 байта приватного ключа + System.arraycopy(pubKey.toByteArray(), 0, full, 32, 32); // дописываем 32 байта публичного ключа + priv = full; // теперь priv содержит полный 64-байтный ключ + } + + // Создаём объект аккаунта для подписи транзакции + Account signer = new Account(priv); + + // Логируем вызов функции и аккаунт, от имени которого он будет происходить + log.debug("Вызов Anchor-функции '{}' от аккаунта {}", functionName, Const.identifyKey(pubKey.toBase58())); + + // Генерируем Anchor-дискриминатор — первые 8 байт SHA-256 хеша строки "global:имя_функции" + byte[] discriminator = MessageDigest + .getInstance("SHA-256") // используем SHA-256 + .digest(("global:" + functionName).getBytes(StandardCharsets.UTF_8)); // хешируем + discriminator = Arrays.copyOf(discriminator, 8); // берём только первые 8 байт (Anchor-дискриминатор) + + // Формируем payload: сначала дискриминатор, потом сериализованные параметры + byte[] data = new byte[discriminator.length + serializedArgs.length]; + System.arraycopy(discriminator, 0, data, 0, discriminator.length); // копируем дискриминатор + System.arraycopy(serializedArgs, 0, data, discriminator.length, serializedArgs.length); // копируем параметры + + // Создаём инструкцию Solana-транзакции: + // - указываем ID программы (куда отправляем) + // - список аккаунтов, задействованных в вызове (AccountMeta) + // - подготовленные данные (дискриминатор + параметры) + TransactionInstruction instruction = new TransactionInstruction( + programId, // ID Solana-программы (Anchor) + accounts, // список аккаунтов + data // бинарные данные вызова + ); + + // Создаём Solana транзакцию и добавляем в неё инструкцию + Transaction tx = new Transaction(); + tx.addInstruction(instruction); + + + // Получаем blockhash + String recentBlockhash = getLatestBlockhash(rpc); + + // отправляем транзакцию + String sig = sendTransactionWithBlockhash(rpc, tx, recentBlockhash, signer); + + log.info("✅ Tx отправлена: {}", sig); + + return sig; // возвращаем base58-подпись транзакции + + } + + // Вспомогательная склейка массивов + public static byte[] concat(byte[]... arrays) { + int length = 0; + for (byte[] a : arrays) length += a.length; + byte[] result = new byte[length]; + int pos = 0; + for (byte[] a : arrays) { + System.arraycopy(a, 0, result, pos, a.length); + pos += a.length; + } + return result; + } + + + /** + * Сериализует аргументы Anchor/Borsh. + * Сейчас поддерживает: string, pubkey. + * - string → 4-байтная длина (LE) + UTF-8 + * - pubkey → 32 байта + */ + public static byte[] encodeAnchorArgs(List types, List values) { + if (types.size() != values.size()) + throw new IllegalArgumentException("Количество типов и значений должно совпадать"); + + ByteBuffer buf = ByteBuffer.allocate(1024).order(ByteOrder.LITTLE_ENDIAN); + + for (int i = 0; i < types.size(); i++) { + String t = types.get(i); + Object v = values.get(i); + + + switch (t) { + case "string": { + byte[] s = (byte[]) v; // уже UTF-8 байты + buf.putInt(s.length); // 4-byte length LE + buf.put(s); + break; + } + case "pubkey": { + byte[] pk = (byte[]) v; + if (pk.length != 32) + throw new IllegalArgumentException("Pubkey должен быть 32 байта"); + buf.put(pk); + break; + } + default: + throw new UnsupportedOperationException("Неизвестный тип: " + t); + } + } + byte[] out = new byte[buf.position()]; + buf.flip(); + buf.get(out); + return out; + } + + + /*------------------------------------------------------------ + * 1. Получаем актуальный blockhash + *-----------------------------------------------------------*/ + @SuppressWarnings("unchecked") + public static String getLatestBlockhash(RpcClient rpc) throws Exception { + + Map commitment = new HashMap(); + commitment.put("commitment", "finalized"); + + Map bhJson; + try { + bhJson = rpc.call( + "getLatestBlockhash", + Collections.singletonList(commitment), + Map.class + ); + // остальной код + } catch (Exception e) { + throw new SolanaException_RpcConnection("Неудаётся соедениться при попытке получить blockhash: " + e.getMessage()); + } + + // --- проверка ответа + поддержка обоих форматов --- + if (bhJson == null) { + throw new SolanaException("При получении номера последнего блока RPC вернул null"); + } + if (bhJson.containsKey("error")) { + throw new SolanaException("При получении номера последнего блока: RPC error: " + bhJson.get("error")); + } + + Map value; + if (bhJson.containsKey("result")) { + Map result = (Map) bhJson.get("result"); + value = (Map) result.get("value"); + } else { + value = (Map) bhJson.get("value"); + } + + if (value == null) { + throw new SolanaException("При получении номера последнего блока: Поле \"value\" отсутствует. Ответ: " + bhJson); + } + String recentBlockhash = (String) value.get("blockhash"); + if (recentBlockhash == null) { + throw new SolanaException("При получении номера последнего блока: Поле \"blockhash\" отсутствует. Ответ: " + bhJson); + } + + return recentBlockhash; + } + + /*------------------------------------------------------------ + * 2. Подписываем и отправляем транзакцию, зная blockhash + *-----------------------------------------------------------*/ + public static String sendTransactionWithBlockhash( + RpcClient rpc, + Transaction tx, + String recentBlockhash, + Account... signers + ) throws Exception { + + /* ---- подставляем hash ---- */ + tx.setRecentBlockHash(recentBlockhash); + + /* ---- подписываем ---- */ + if (signers.length == 0) { + throw new IllegalArgumentException("Нужен хотя бы один подписант"); + } else if (signers.length == 1) { + tx.sign(signers[0]); + } else { + tx.sign(Arrays.asList(signers)); + } + + +/** // можно сериализовывать в базу 64 и в базу 58 // пока оставил 58 +// // ---- сериализация в база 64 ---- +// String b64Tx = Base64.getEncoder() +// .encodeToString(tx.serialize()); +// +// // ---- отправка ---- +// Map cfg = new HashMap(); +// cfg.put("skipPreflight", Boolean.FALSE); //Boolean.TRUE); +// +// cfg.put("encoding", "base64"); // ← ключевое добавление! +// +// +// return rpc.call( +// "sendTransaction", +// Arrays.asList(b64Tx, cfg), +// String.class +// ); + */ + + /* ---- сериализация и отправка в база 58 ---- */ + byte[] txBytes = tx.serialize(); + String base58EncodedTx = Base58.encode(txBytes); + + Map cfg = new HashMap<>(); + cfg.put("skipPreflight", false); // если false - то транзакцию сразу проверяют на ошибки + + try { + return rpc.call( + "sendTransaction", + Arrays.asList(base58EncodedTx, cfg), + String.class + ); + } catch (RpcException e) { + /* ---------- низкоуровневые сетевые ошибки (не достучались до RPC) */ + Throwable cause = e.getCause(); + if (cause instanceof ConnectException) { + throw new SolanaException_RpcConnection("Не удалось подключиться к RPC-узлу: " + cause.getMessage()); + } + if (cause instanceof SocketTimeoutException) { + throw new SolanaException_RpcConnection("Время ожидания ответа RPC истекло"); + } + + /* ---------- парсинг сообщения об ошибке от RPC/симуляции -------- */ + String err = Objects.toString(e.getMessage(), ""); + + /* 1) Стандартные InstructionError-ы */ + if (err.contains("\"InstructionError\"")) { + // Чаще всего приходит: "InstructionError": [0,"InsufficientFunds"] + if (err.contains("InsufficientFunds")) { + throw new SolanaException_InsufficientFundsForFee(); + } +// if (err.contains("AccountNotFound")) { +// throw new SolanaException_AccountNotFound(); +// } +// if (err.contains("InvalidAccountData")) { +// throw new SolanaException_InvalidAccountData(); +// } +// if (err.contains("InstructionMissing")) { +// throw new SolanaException_InstructionMissing(); +// } +// if (err.contains("UninitializedAccount")) { +// throw new SolanaException_UninitializedAccount(); +// } +// if (err.contains("IncorrectProgramId")) { +// throw new SolanaException_IncorrectProgramId(); +// } + } + + /* ) Отдельная проверка на ошибку дебета с пустого аккаунта */ + if (err.contains("insufficient funds for rent") // или такое сообщение если акаунт пуст + || err.matches("(?i).*custom program error: 0x0*1\\b.*")) { // или такое если денег не хватает + throw new SolanaException_InsufficientFundsForFee(); + } + + /* 2) Кастомная ошибка из твоей программы: "custom program error: 0xXXXX" */ + Pattern p = Pattern.compile("custom program error: (0x[0-9a-fA-F]+)"); + Matcher m = p.matcher(err); + if (m.find()) { + String hexCode = m.group(1); + int decimalCode = Integer.parseInt(hexCode.substring(2), 16); + throw new SolanaException_InProgram(decimalCode); + } + + /* 3) Прочие симуляционные ошибки (можно расширять по вкусу) */ +// if (err.contains("Transaction simulation failed")) { +// throw new SolanaException( +// "Симуляция транзакции завершилась ошибкой: " + err +// ); +// } + + /* 4) Всё остальное – оборачиваем как «неизвестную» */ + throw new SolanaException("RPC-ошибка: " + err, e); + + } + } + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaRpcClient.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaRpcClient.java new file mode 100644 index 0000000..6709444 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/SolanaRpcClient.java @@ -0,0 +1,86 @@ +package me.shineup.solana.internal.utils; + +import me.shineup.solana.config.Const; +import me.shineup.solana.exceptions.SolanaException_RpcConnection; +import me.shineup.solana.exceptions.SolanaErrorHandler; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; + +public class SolanaRpcClient { + + private static final Logger log = LoggerFactory.getLogger(SolanaRpcClient.class); + private static SolanaRpcClient instance; + + private final OkHttpClient httpClient; + private final String rpcUrl; + + private static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); + + private SolanaRpcClient(String rpcUrl) { + this.rpcUrl = rpcUrl; + this.httpClient = new OkHttpClient(); + } + + public static SolanaRpcClient getInstance() { + if (instance == null) { + instance = new SolanaRpcClient(Const.RPC_URL); + } + return instance; + } + + public static SolanaRpcClient withCustomUrl(String customUrl) { + instance = new SolanaRpcClient(customUrl); + return instance; + } + + /** + * Выполняет JSON-RPC запрос и возвращает ответ как строку. + * В случае ошибки — выбрасывает RpcConnectionException. + */ + public String sendRequest(String jsonRequest) throws SolanaException_RpcConnection { + log.debug("📤 Отправка RPC-запроса: {}", jsonRequest); + + RequestBody body = RequestBody.create(jsonRequest, JSON); + + Request request = new Request.Builder() + .url(rpcUrl) + .post(body) + .addHeader("Content-Type", "application/json") + .build(); + + try (Response response = httpClient.newCall(request).execute()) { + if (!response.isSuccessful()) { + log.error("❌ RPC ответ с ошибкой: {} {}", response.code(), response.message()); + throw new SolanaException_RpcConnection("RPC ответ с ошибкой: " + response.code() + " " + response.message()); + } + + if (response.body() == null) { + log.error("❌ RPC вернул пустое тело"); + throw new SolanaException_RpcConnection("Пустой ответ от RPC"); + } + + String responseText = response.body().string(); + log.debug("📥 Получен ответ от RPC: {}", responseText); + + // ✅ Обработка ошибок, если в ответе есть error + if (responseText.contains("\"error\"")) { + SolanaErrorHandler.handleRpcJsonError(responseText); + } + + return responseText; + + } catch (IOException e) { + log.error("❌ Ошибка подключения к RPC: {}", e.toString()); + throw new SolanaException_RpcConnection("Ошибка подключения к RPC" + e.toString()); + } catch (Exception e) { + log.error("❌ Непредвиденная ошибка при вызове RPC: {}", e.toString()); + throw new SolanaException_RpcConnection("Непредвиденная ошибка RPC" + e.toString()); + } + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/jsonrpc/JsonRpcRequest.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/jsonrpc/JsonRpcRequest.java new file mode 100644 index 0000000..66310a8 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/jsonrpc/JsonRpcRequest.java @@ -0,0 +1,19 @@ +package me.shineup.solana.internal.utils.jsonrpc; + + + +import java.util.List; + + +/** странная фигня котыль который пришлось добавить при переходе на старую библиотеку solanaj для джава 8 */ +public class JsonRpcRequest { + public String jsonrpc = "2.0"; + public String method; + public List params; + public int id = 1; + + public JsonRpcRequest(String method, List params) { + this.method = method; + this.params = params; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/reader/PdaReader.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/reader/PdaReader.java new file mode 100644 index 0000000..1351eea --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/reader/PdaReader.java @@ -0,0 +1,157 @@ +package me.shineup.solana.internal.utils.reader; + + +import me.shineup.solana.exceptions.SolanaException_RpcConnection; +import me.shineup.solana.exceptions.SolanaException; +import org.p2p.solanaj.core.PublicKey; +import org.p2p.solanaj.rpc.RpcClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; + +import java.nio.charset.StandardCharsets; +import java.util.*; + +/** + * Чтение произвольного PDA-аккаунта в актуальных кластерах Solana (v1.18+). + * + * ─────────────────────────────────────────────────────────────────────────────── + * ▸ Solana HTTP RPC: getAccountInfo + * + * { + * "jsonrpc":"2.0", + * "id":1, + * "result":{ + * "context":{"slot":123456}, + * "value":{ + * "data":[ // 0 - base64-строка, 1 - "base64" + * "BASE64_STRING", + * "base64" + * ], + * "executable":false, + * "lamports":2039280, + * "owner":"BPFLoaderUpgradeab1e11111111111111111111111", + * "rentEpoch":"18446744073709551615" // - строка-u64 (v1.18+) + * } + * } + * } + * + * ▸ Мы читаем только value.data[0] (Base64) – остальное не трогаем, + * поэтому не важен тип rentEpoch (строка или число). + * ─────────────────────────────────────────────────────────────────────────────── + */ +public final class PdaReader { + + /* --------------------------------------------------------------------- */ + /* CONFIG & LOG */ + /* --------------------------------------------------------------------- */ + private static final Logger LOG = LoggerFactory.getLogger(PdaReader.class); + private static final RpcClient RPC = new RpcClient(Const.RPC_URL); // один клиент на класс + + private PdaReader() {} // запретить new + + /* --------------------------------------------------------------------- */ + /* PUBLIC API */ + /* --------------------------------------------------------------------- */ + + /** Чтение PDA, вычисленного из одного текстового сида. */ + public static byte[] readOneSeed(String seed, String programId) throws Exception { + PublicKey pda = derivePda(Collections.singletonList(seed.getBytes(StandardCharsets.UTF_8)), + programId); + return fetchAccountData(pda); + } + + /** Чтение PDA, вычисленного из двух произвольных сид-массивов. */ + public static byte[] readTwoSeeds(byte[] seed1, byte[] seed2, String programId) throws Exception { + PublicKey pda = derivePda(Arrays.asList(seed1, seed2), programId); + return fetchAccountData(pda); + } + + /* --------------------------------------------------------------------- */ + /* INTERNALS */ + /* --------------------------------------------------------------------- */ + + /** Высчитываем адрес PDA для списка сидов. */ + private static PublicKey derivePda(List seeds, String programId) throws Exception { + PublicKey program = new PublicKey(programId); + PublicKey pda = PublicKey.findProgramAddress(seeds, program).getAddress(); + LOG.info("📡 PDA адрес: {}", pda.toBase58()); + return pda; + } + + /** + * Достаём бинарные данные аккаунта.
+ * Возвращает null, если аккаунт отсутствует или пуст. + */ + + + @SuppressWarnings("unchecked") + private static byte[] fetchAccountData(PublicKey pda) throws Exception { + + // 1) getAccountInfo c base64-энкодингом + Map cfg = new HashMap<>(); + cfg.put("encoding", "base64"); + cfg.put("commitment", "confirmed"); + +// Map resp = RPC.call( +// "getAccountInfo", +// Arrays.asList(pda.toBase58(), cfg), +// Map.class // сырое дерево +// ); + + + + Map resp; + try { + resp = RPC.call( + "getAccountInfo", + Arrays.asList(pda.toBase58(), cfg), + Map.class + ); + } catch (Exception e) { // solanaj бросает RuntimeException/IOException + throw new SolanaException_RpcConnection("Не удалось выполнить getAccountInfo"); + } + + // Если RPC вернул стандартное поле error — разбираем его централизованно + if (resp.get("error") != null) { + throw new SolanaException("RPC вернул поле error"); //тут можно добавить вывод что за конкретная ошибка случилась + } + + // 2) Достаём value → data[0] +// Map result = (Map) resp.get("result"); +// if (result == null) return null; + + + Map value = (Map) resp.get("value");//result.get("value"); + if (value == null) return null; + + List dataArr = (List) value.get("data"); + if (dataArr == null || dataArr.isEmpty()) return null; + + String b64 = (String) dataArr.get(0); // ← вот он payload + if (b64 == null || b64.isEmpty()) return null; + + return Base64.getDecoder().decode(b64); + } + + @SuppressWarnings("unchecked") + private static void debugDumpJson(Object node, int indent) { + String pad = String.join("", Collections.nCopies(indent, " ")); // два пробела × indent + if (node instanceof Map) { + Map map = (Map) node; + for (Map.Entry e : map.entrySet()) { + System.out.println(pad + e.getKey() + ":"); + debugDumpJson(e.getValue(), indent + 1); + } + } else if (node instanceof Iterable) { + Iterable it = (Iterable) node; + for (Object val : it) { + debugDumpJson(val, indent + 1); + } + } else { + System.out.println(pad + String.valueOf(node)); + } + } + + +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/ResultChecker.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/ResultChecker.java new file mode 100644 index 0000000..5ff55ab --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/ResultChecker.java @@ -0,0 +1,29 @@ +package me.shineup.solana.internal.utils.resultChecker; + + +/** + * Утилита для проверки результата выполнения транзакции по подписи. + * + * Данный класс: + * - выводит подпись транзакции в консоль + * - ждёт подтверждения транзакции через Solana RPC + * - выводит статус транзакции после завершения + */ +public class ResultChecker { + + /** + * Проверяет статус транзакции по её подписи. + * + * @param sig Подпись (signature) транзакции в base58-формате. + */ + public static void check(String sig) { + System.out.println("📦 Signature: " + sig); + + if (sig != null) { + TransactionStatusChecker.waitForConfirmation(sig); + SolanaTransactionStatusChecker.getTransactionStatus(sig); + } else { + System.out.println("⚠️ Подпись транзакции пуста или null"); + } + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/SolanaTransactionStatusChecker.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/SolanaTransactionStatusChecker.java new file mode 100644 index 0000000..a0d7cb5 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/SolanaTransactionStatusChecker.java @@ -0,0 +1,210 @@ +package me.shineup.solana.internal.utils.resultChecker; + +import me.shineup.solana.config.Const; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.internal.utils.SolanaRpcClient; + +public class SolanaTransactionStatusChecker { + + private static final Logger log = LoggerFactory.getLogger(SolanaTransactionStatusChecker.class); + private static final Gson gson = new Gson(); + + + public static boolean getTransactionStatus(String signature) { + boolean isOk = false; + String requestJson = String.format( + "{\n" + + " \"jsonrpc\": \"2.0\",\n" + + " \"id\": 1,\n" + + " \"method\": \"getTransaction\",\n" + + " \"params\": [\"%s\", { \"encoding\": \"jsonParsed\", \"commitment\": \"finalized\" }]\n" + + "}", signature); + +// String requestJson = """ +// { +// "jsonrpc": "2.0", +// "id": 1, +// "method": "getTransaction", +// "params": ["%s", { "encoding": "jsonParsed", "commitment": "finalized" }] +// } +// """.formatted(signature); + + + try { + String responseJson = SolanaRpcClient.getInstance().sendRequest(requestJson); + JsonObject root = gson.fromJson(responseJson, JsonObject.class); + + if (root.has("error")) { + log.error("❌ Ошибка при запросе транзакции: {}", root.get("error")); + return false; + } + + JsonElement resultElement = root.get("result"); + + if (resultElement == null || resultElement.isJsonNull()) { + log.warn("⚠️ Транзакция с сигнатурой {} не найдена или ещё не финализирована", signature); + return false; + } + + JsonObject result = root.getAsJsonObject("result"); + + if (result == null) { + log.warn("⚠️ Транзакция с сигнатурой {} не найдена", signature); + return false; + } + + JsonObject meta = result.getAsJsonObject("meta"); + if (meta == null) { + log.warn("⚠️ Нет информации о результате выполнения"); + return false; + } + + JsonElement err = meta.get("err"); + if (err == null || err.isJsonNull()) { + log.info("✅ Транзакция завершилась успешно"); + isOk = true; + } else { + log.warn("⚠️ Транзакция завершилась с ошибкой. Код ошибки: {}", extractCustomErrorCode(err)); + isOk = false; + } + + + // 💸 Вывод комиссии + if (meta.has("fee")) { + long fee = meta.get("fee").getAsLong(); + log.info("💸 Комиссия за транзакцию: {} лампортов", fee); + } + + // Получаем message → accountKeys + JsonObject message = result.getAsJsonObject("transaction").getAsJsonObject("message"); + JsonArray accountKeys = message.getAsJsonArray("accountKeys"); + + // 🔄 Выводим изменения балансов + logBalanceChanges(meta, accountKeys); + + // 💸 Общая сумма списанных лампортов (не только комиссия) + long totalSpent = calculateTotalSpent(meta); + log.info("💸 Общая сумма списанных лампортов (включая переводы и аренду аккаунтов): {}", totalSpent); + + + // Выводим лог исполнения (если есть) + if (meta.has("logMessages")) { + JsonElement logsElement = meta.get("logMessages"); + if (logsElement != null && logsElement.isJsonArray()) { + JsonArray logs = logsElement.getAsJsonArray(); + log.info("📝 Логи исполнения:"); + for (JsonElement logLine : logs) { + log.info(" → " + logLine.getAsString()); + } + } else if (logsElement != null && logsElement.isJsonNull()) { + log.info("📝 Логи исполнения: отсутствуют (null)"); + } else { + log.warn("📝 Логи исполнения: неожиданный формат данных"); + } + } + + } catch (Exception e) { + log.error("❌ Ошибка при запросе статуса транзакции", e); + return false; + } + return isOk; + } + + + + + /** + * Извлекает значение Custom Anchor ошибки из поля "err", если оно есть. + * + * Пример ожидаемого JSON: + * { + * "InstructionError": [0, { "Custom": 10000 }] + * } + * + * @param errJson поле "err" из ответа Solana + * @return числовой код ошибки (например, 10000) или null, если не найден + */ + public static Integer extractCustomErrorCode(JsonElement errJson) { + if (errJson == null || errJson.isJsonNull()) return null; + + try { + JsonObject errObj = errJson.getAsJsonObject(); + if (errObj.has("InstructionError")) { + JsonArray instrError = errObj.getAsJsonArray("InstructionError"); + + if (instrError.size() == 2 && instrError.get(1).isJsonObject()) { + JsonObject customObj = instrError.get(1).getAsJsonObject(); + if (customObj.has("Custom")) { + return customObj.get("Custom").getAsInt(); + } + } + } + } catch (Exception e) { + // безопасно возвращаем null + } + + return null; + } + + + /** + * Логирует изменения балансов всех аккаунтов, участвующих в транзакции. + * + * @param meta JSON-объект "meta" из транзакции (включает preBalances и postBalances) + * @param accountKeys Список accountKeys из message (содержит pubkey для каждого аккаунта) + */ + public static void logBalanceChanges(JsonObject meta, JsonArray accountKeys) { + JsonArray preBalances = meta.getAsJsonArray("preBalances"); + JsonArray postBalances = meta.getAsJsonArray("postBalances"); + + log.info("💰 Изменения балансов по аккаунтам:"); + + for (int i = 0; i < preBalances.size(); i++) { + long pre = preBalances.get(i).getAsLong(); + long post = postBalances.get(i).getAsLong(); + long delta = post - pre; + + String pubkey = accountKeys.get(i) + .getAsJsonObject() + .get("pubkey") + .getAsString(); + + double usdValue = delta * 150.0 / 1_000_000_000; + String usdFormatted = String.format("%.5f", usdValue); + + log.info("🔄 {}: {} → {} (Δ: {} лампортов) ≈ {} $", Const.identifyKey(pubkey), pre, post, delta, usdFormatted); + + + } + } + + /** + * Считает общую сумму списанных лампортов по всем аккаунтам, + * т.е. где postBalance < preBalance. + * + * @param meta JSON-объект "meta" из транзакции + * @return общее количество списанных лампортов + */ + public static long calculateTotalSpent(JsonObject meta) { + JsonArray preBalances = meta.getAsJsonArray("preBalances"); + JsonArray postBalances = meta.getAsJsonArray("postBalances"); + + long totalSpent = 0; + + for (int i = 0; i < preBalances.size(); i++) { + long pre = preBalances.get(i).getAsLong(); + long post = postBalances.get(i).getAsLong(); + + if (post < pre) { + totalSpent += (pre - post); + } + } + + return totalSpent; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusChecker.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusChecker.java new file mode 100644 index 0000000..44bca8f --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusChecker.java @@ -0,0 +1,68 @@ +package me.shineup.solana.internal.utils.resultChecker; + +import org.p2p.solanaj.rpc.RpcClient; +import org.p2p.solanaj.rpc.types.SignatureStatuses; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import me.shineup.solana.config.Const; + +import java.util.Collections; +import java.util.List; + +public class TransactionStatusChecker { + + private static final Logger LOG = LoggerFactory.getLogger(TransactionStatusChecker.class); + + /** + * Проверяет статус транзакции по подписи, делает до 10 попыток с паузой. + * + * @param signature Подпись транзакции (Base58) + * @return true, если транзакция прошла успешно, иначе false + */ + public static boolean waitForConfirmation(String signature) { + RpcClient rpc = new RpcClient(Const.RPC_URL); + + try { + for (int attempt = 1; attempt <= 10; attempt++) { + LOG.info("🔍 Попытка {} проверки транзакции {}", attempt, signature); + + SignatureStatuses statuses = rpc.getApi().getSignatureStatuses(Collections.singletonList(signature), true); + List infoList = statuses.getValue(); + + if (infoList != null && !infoList.isEmpty()) { + SignatureStatuses.Value info = infoList.get(0); + + if (info != null) { + String status = info.getConfirmationStatus(); // Или getConfirmationStatusString() в других версиях + + LOG.info("⏳ Статус: {}", status); + if ("finalized".equals(status)) { + LOG.info("🎉 Финализирована большинством"); + //todo + return true; + } else if ("processed".equals(status)) { + LOG.info("Транзакция принята в пул"); + } else if ("confirmed".equals(status)) { + LOG.info("Транзакция вошла в блок, но не финализирована"); + } else { + LOG.info("Хер его знает "); + } + + } else { + LOG.info("Пока такой транзакции нету"); + } + } else { + LOG.info("Запрос вообще не удался"); + } + + Thread.sleep(3000); // Ждать 3 секунды перед следующей попыткой + } + + LOG.warn("❌ Транзакция не подтвердилась за 10 попыток: {}", signature); + } catch (Exception e) { + LOG.error("❌ Ошибка при проверке транзакции", e); + } + + return false; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusHelper.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusHelper.java new file mode 100644 index 0000000..cf6bb4b --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/internal/utils/resultChecker/TransactionStatusHelper.java @@ -0,0 +1,126 @@ +package me.shineup.solana.internal.utils.resultChecker; + +// Демонстрационный класс: единая точка проверки статуса транзакции Solana +// ---------------------------------------------------------------------- +// Содержит: +// 1. Enum TxStatus – перечень возможных состояний +// 2. Статический метод getTxStatus(...) – собственно проверка +// 3. Метод main(...) – пример использования +// ---------------------------------------------------------------------- + +import java.util.Collections; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.utils.SolanaRpcClient; +import me.shineup.solana.model.TxStatus; +import org.p2p.solanaj.rpc.RpcClient; +import org.p2p.solanaj.rpc.types.SignatureStatuses; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TransactionStatusHelper { + +// // -------------------------------------------------- +// // 1. Enum – возможные состояния транзакции +// // -------------------------------------------------- +// public enum TxStatus { +// // ✅ Повторять запрос, если лимит времени не исчерпан: +// NOT_FOUND, // RPC‑узел ещё не видел подпись */ +// PROCESSED, // Подпись обработана, но не попала в блок +// CONFIRMED, // Транзакция в блоке, но блок не финализирован +// +// //❌ Не повторять, даже если лимит не исчерпан: +// FINALIZED_SUCCESS, // Блок финализирован и meta.err == null +// FINALIZED_ERROR, // Блок финализирован, но meta.err содержит ошибку +// //⚠️ Не повторять или повторять ограниченно (1–3 раза, или ≤ N секунд): +// UNKNOWN, // Не удалось определить статус (RPC‑ошибка, исключение и т.д.) */ +// NETWORK_ERROR // Не удаётся подключиться по сете +// } + + // -------------------------------------------------- + // 2. Метод проверки статуса + // -------------------------------------------------- + private static final Logger log = LoggerFactory.getLogger(TransactionStatusHelper.class); + + /** + * Универсальная проверка статуса транзакции. + * @param signature подпись (transaction signature / id) + * @return текущее состояние {@link TxStatus} + */ + public static TxStatus getTxStatus(String signature) { + RpcClient rpc = new RpcClient(Const.RPC_URL); + + try { + // --- 1. Быстрый запрос STATUSES + // Пробуем получить статус транзакции + SignatureStatuses.Value info; + try { + info = rpc.getApi() + .getSignatureStatuses(Collections.singletonList(signature), true) + .getValue() + .get(0); + } catch (Exception e) { + log.error("🔌 Ошибка подключения к RPC или сети", e); + return TxStatus.NETWORK_ERROR; // Тут можно вернуть специальный статус NETWORK_ERROR, если нужно точнее + } + + + + if (info == null) { + return TxStatus.NOT_FOUND; // подпись ещё не дошла до RPC + } + + String commit = info.getConfirmationStatus(); // processed / confirmed / finalized + + switch (commit) { + case "processed": + return TxStatus.PROCESSED; + case "confirmed": + return TxStatus.CONFIRMED; + case "finalized": + // --- 2. Дошли до финала – нужен getTransaction, чтобы узнать err + String reqJson = String.format( + "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getTransaction\"," + + "\"params\":[\"%s\",{\"encoding\":\"json\",\"commitment\":\"finalized\"}]}", + signature); + + // SolanaRpcClient – ваша внутренняя обёртка. Замените на свой http‑клиент. + String raw = SolanaRpcClient.getInstance().sendRequest(reqJson); + + JsonObject meta = JsonParser.parseString(raw) + .getAsJsonObject() + .getAsJsonObject("result") + .getAsJsonObject("meta"); + + return meta.get("err").isJsonNull() ? TxStatus.FINALIZED_SUCCESS : TxStatus.FINALIZED_ERROR; + default: + return TxStatus.UNKNOWN; + } + + } catch (Exception e) { + log.error("RPC error while checking {}", signature, e); + return TxStatus.UNKNOWN; + } + } + + // -------------------------------------------------- + // 3. Пример использования + // -------------------------------------------------- + /** + * Точка входа для быстрого ручного теста. + * Запускайте так: + * java TransactionStatusHelper + * Если аргумент не передан, используется демо‑подпись. + */ + public static void main(String[] args) { + // Подпись можно передать первым аргументом + String sig = (args.length > 0) + ? args[0] + : "4bxeRu4pNk9UzN6QgTPy6Q3DLJ6ZQt3xMkUQnDzohBpxjMVqRyba2Riqm8o7MBYo2YfSfvqbMFxRRWwu1XbbeiKf"; + + TxStatus status = getTxStatus(sig); + System.out.println("Статус транзакции " + sig + " → " + status); + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/TxStatus.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/TxStatus.java new file mode 100644 index 0000000..5c86b9a --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/TxStatus.java @@ -0,0 +1,22 @@ +package me.shineup.solana.model; + +/** + * Статус транзакции в Solana. + * Используется для отслеживания состояния по сигнатуре. + */ +// -------------------------------------------------- +// 1. Enum – возможные состояния транзакции +// -------------------------------------------------- +public enum TxStatus { + // ✅ Повторять запрос, если лимит времени не исчерпан: + NOT_FOUND, // RPC‑узел ещё не видел подпись */ + PROCESSED, // Подпись обработана, но не попала в блок + CONFIRMED, // Транзакция в блоке, но блок не финализирован + + //❌ Не повторять, даже если лимит не исчерпан: + FINALIZED_SUCCESS, // Блок финализирован и meta.err == null + FINALIZED_ERROR, // Блок финализирован, но meta.err содержит ошибку + //⚠️ Не повторять или повторять ограниченно (1–3 раза, или ≤ N секунд): + UNKNOWN, // Не удалось определить статус (RPC‑ошибка, исключение и т.д.) */ + NETWORK_ERROR // Не удаётся подключиться по сете +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserById.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserById.java new file mode 100644 index 0000000..8dea416 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserById.java @@ -0,0 +1,52 @@ +package me.shineup.solana.model; + + +import java.util.List; + +/** + * Java-представление Solana-структуры UserById. + * + * Содержит: + * • format – версия сериализации; + * • id – числовой ID пользователя; + * • login – строковый логин; + * • pubkey – публичная подпись пользователя (Base58); + * • deviceCount – сколько устройств хранится; + * • devices – список устройств (DeviceInfo). + */ +public class UserById { + + /* ---------- поля, идущие в сериализации ---------- */ + public int format; + public long id; + public String login; + public String pubkey; + public int deviceCount; + public List devices; + + /** Вложенный класс описания одного устройства. */ + public static class DeviceInfo { + public int deviceType; // 1 байт в on-chain + public String devicePubkey; // 32 байта (Base58) + public String x25519Pubkey; // 32 байта (Base58) + + @Override + public String toString() { + return "DeviceInfo{type=" + deviceType + + ", devPub=" + devicePubkey + + ", x25519=" + x25519Pubkey + '}'; + } + } + + @Override + public String toString() { + return "UserById{" + + "format=" + format + + ", id=" + id + + ", login='" + login + '\'' + + ", pubkey='" + pubkey + '\'' + + ", deviceCount=" + deviceCount + + ", devices=" + devices + + '}'; + } +} diff --git a/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserByLogin.java b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserByLogin.java new file mode 100644 index 0000000..a53e420 --- /dev/null +++ b/solana-shine-client-lib/solana-shine-lib/src/main/java/me/shineup/solana/model/UserByLogin.java @@ -0,0 +1,23 @@ +package me.shineup.solana.model; + +/** + * Класс описывающий объект UserByLogin, аналогичный структуре на стороне Solana. + */ +public class UserByLogin { + public int format; // формат сериализации (например, 1) + public String login; // логин + public long id; // числовой ID + public String pubkey; // публичный ключ (base58) + public int status; // статус (например, 0) + + @Override + public String toString() { + return "UserByLogin{" + + "format=" + format + + ", login='" + login + '\'' + + ", id=" + id + + ", pubkey='" + pubkey + '\'' + + ", status=" + status + + '}'; + } +} \ No newline at end of file diff --git a/solana-shine-client-lib/src/main/Build.txt b/solana-shine-client-lib/src/main/Build.txt new file mode 100644 index 0000000..ef4c9fd --- /dev/null +++ b/solana-shine-client-lib/src/main/Build.txt @@ -0,0 +1,2 @@ +./gradlew :solana-shine-lib:build +- команда что бы сбилдить библиотеку \ No newline at end of file diff --git a/solana-shine-client-lib/src/main/airDrop.txt b/solana-shine-client-lib/src/main/airDrop.txt new file mode 100644 index 0000000..a27d170 --- /dev/null +++ b/solana-shine-client-lib/src/main/airDrop.txt @@ -0,0 +1 @@ +solana airdrop 1 HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA --url https://api.devnet.solana.com diff --git a/solana-shine-client-lib/src/main/java/com/shine/solana/test/AddUserExemple.java b/solana-shine-client-lib/src/main/java/com/shine/solana/test/AddUserExemple.java new file mode 100644 index 0000000..cec2458 --- /dev/null +++ b/solana-shine-client-lib/src/main/java/com/shine/solana/test/AddUserExemple.java @@ -0,0 +1,118 @@ +package com.shine.solana.test; + +import me.shineup.solana.SolanaWrapper; +import me.shineup.solana.internal.standartActions.keysGenerator.KeyPairBase58; +import me.shineup.solana.config.Const; +import me.shineup.solana.SolanaTxWatcher; +import me.shineup.solana.model.TxStatus; + +public class AddUserExemple { + public static void main(String[] args) { +try { +// SolanaWrapper.setRPC_URL_testNet(); +// SolanaWrapper.requestAirdrop(Const.getKeyByName("key3").getPublicKey(), 1); + SolanaWrapper.getBalance(Const.getKeyByName("key3").getPublicKey()); + +// long id =1; +// try { +// UserById u = SolanaWrapper.getUserById(id); +// System.out.println(u); +// UserByLogin u2 =SolanaWrapper.getUserByLogin(u.login); +// System.out.println(u2); +// } catch (Exception e) { +// e.printStackTrace(); +// } + + KeyPairBase58 k = SolanaWrapper.generateNewWallet(); + + String sig; +// sig = SolanaWrapper.sendSol(Const.getKeyByName("key1").getPrivateKey(), k.publicKey, 100000000); + SolanaWrapper.getBalance(Const.getKeyByName("key1").getPublicKey()); +// SolanaWrapper.getBalance(k.publicKey); +// SolanaWrapper.getBalance(k.publicKey); +// SolanaWrapper.getBalance(k.publicKey); + + +// String sig = SolanaWrapper.registerUserWithOneDev(k.publicKey,k.privateKey,"ivan11263456",k.publicKey, k.publicKey); + + sig = SolanaWrapper.registerUserWithOneDev(Const.getKeyByName("key1").getPublicKey(), Const.getKeyByName("key1").getPrivateKey(), + "ivan1261", Const.getKeyByName("key1").getPublicKey(), Const.getKeyByName("key1").getPublicKey()); + + + SolanaTxWatcher watcher = new SolanaTxWatcher(sig); + while (watcher.shouldRetry()) { // ◀ проверяем, нужно ли ещё опрашивать + watcher.updateStatus(); // ◀ запрашиваем статус через RPC + System.out.println( + watcher.getStatus() + " | " + // ◀ печатаем статус + watcher.getStatusComment()); + try { + Thread.sleep(SolanaTxWatcher.getRetryIntervalMs()); // ◀ ждём секунду + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if (watcher.isSuccess()) { + System.out.println("✅ Транзакция прошла успешно!"); + } else { + System.out.println("❌ Завершили слежение без успеха."); + } + + +// TxStatus st = SolanaWrapper.getTransactionStatus(sig); +// System.out.println("Статус транзакции " + sig + " → " + st); +// TxStatus result = waitTransactionFinalized(sig); +// +// System.out.println("Итоговый статус: " + result); +// if (result == TxStatus.FINALIZED_SUCCESS) { +// System.out.println("✅ Транзакция прошла успешно!"); +// } else if (result == TxStatus.FINALIZED_ERROR) { +// System.out.println("❌ Транзакция завершилась с ошибкой."); +// } + +} catch (Exception e) { + throw new RuntimeException(e); +} + } + + + /** + * Ожидает финализации транзакции, проверяя статус каждую секунду. + * Максимальное время ожидания — 20 секунд. + */ + public static TxStatus waitTransactionFinalized(String signature) { + final int maxSeconds = 20; + TxStatus st; + for (int i = 0; i < maxSeconds; i++) { + try { + st = SolanaWrapper.getTransactionStatus(signature); + } catch (Exception e) { + throw new RuntimeException(e); //и тут дописывать проверки если надо + } + System.out.println("Статус транзакции " + signature + " → " + st); + + // Если достигли финального состояния — возвращаем + if (st == TxStatus.FINALIZED_SUCCESS || st == TxStatus.FINALIZED_ERROR) { + return st; + } + + // Если транзакция не найдена или в неизвестном состоянии — тоже выходим + if (st == TxStatus.UNKNOWN) { + System.out.println("Ошибка или подпись не найдена. Прерываем ожидание."); + return st; + } + + // Подождать 1 секунду + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + System.out.println("Ожидание прервано."); + return TxStatus.UNKNOWN; + } + } + + System.out.println("⏱ Превышен лимит ожидания (20 сек)."); + return TxStatus.UNKNOWN; + } + +} diff --git a/solana-shine-client-lib/src/main/java/com/shine/solana/test/AirDrop.java b/solana-shine-client-lib/src/main/java/com/shine/solana/test/AirDrop.java new file mode 100644 index 0000000..a85cfe8 --- /dev/null +++ b/solana-shine-client-lib/src/main/java/com/shine/solana/test/AirDrop.java @@ -0,0 +1,32 @@ +package com.shine.solana.test; + +import me.shineup.solana.SolanaWrapper; +import me.shineup.solana.config.Const; + +public class AirDrop { + public static void main(String[] args) { + // Если первый аргумент равен строке "1" → запрашиваем airdrop, + // иначе просто выводим баланс. + try { +// SolanaWrapper.setRPC_URL("https://api.testnet.solana.com"); + // SolanaWrapper.setRPC_URL("https://api.devnet.solana.com"); + boolean needAirdrop = args.length > 0 && "1".equals(args[0]); + // needAirdrop = true; + if (needAirdrop) { + long oneSolLamports = 1_000_000_000L; // 1 SOL в лампортах + SolanaWrapper.requestAirdrop( + Const.getKeyByName("key1").getPublicKey(), + oneSolLamports); + } else { + SolanaWrapper.getBalance(Const.getKeyByName("key1").getPublicKey()); + SolanaWrapper.getBalance(Const.getKeyByName("key2").getPublicKey()); + SolanaWrapper.getBalance(Const.getKeyByName("key3").getPublicKey()); + } + + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + +} diff --git a/solana-shine-client-lib/src/main/java/com/shine/solana/test/Main.java b/solana-shine-client-lib/src/main/java/com/shine/solana/test/Main.java new file mode 100644 index 0000000..22c4ecf --- /dev/null +++ b/solana-shine-client-lib/src/main/java/com/shine/solana/test/Main.java @@ -0,0 +1,47 @@ +package com.shine.solana.test; + + +import me.shineup.solana.SolanaWrapper; +import me.shineup.solana.config.Const; +import me.shineup.solana.internal.callSolanaFunc.InitializeUserCounter.InitializeUserCounter; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Main { + private static final ExecutorService executorService = Executors.newCachedThreadPool(); + + public static void main(String[] args) { +// SolanaWrapper.setRPC_URL("https://api.devnet.solana.com"); +// InitializeUserCounter + + long oneSolLamports = 5_000_000_000L; // 1 SOL в лампортах + + try { + SolanaWrapper.requestAirdrop( + "FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P", + oneSolLamports); + System.out.println(SolanaWrapper.getBalance("FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P"));//H6q58ytZk5sd3KQisC57R6urKUjn5PaWKLCv7sNZtj4i")); + System.out.println("Баланс Shine" + SolanaWrapper.getBalance( "jZnbqzrbKaksVomiqAxsKGiz5ct8rHPgcNDiiKyTZDD")); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + + // 5RpEoxRKSr2norQP3vEnq9XokQGh9EbGN8q8xUUVAdm1M5mTD1vMuyJPYJfViMWFf6c8qT5mj2bt64gLE2zm6VG3 - тестовые в фантом валет + // FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P + + // +// executorService.submit(() -> { +// try { +// System.out.println(SolanaWrapper.getUserById(1).login); +// } catch (Exception e) { +// System.out.println(e.getMessage()); +// } +// }); + + + + + } + +} diff --git a/solana-shine-client-lib/src/main/java/com/shine/utils/CreateToken_story.txt b/solana-shine-client-lib/src/main/java/com/shine/utils/CreateToken_story.txt new file mode 100644 index 0000000..b2c0623 --- /dev/null +++ b/solana-shine-client-lib/src/main/java/com/shine/utils/CreateToken_story.txt @@ -0,0 +1,58 @@ +ai@ai-home:~$ ~/.cargo/bin/spl-token --version +spl-token-cli 5.3.0 + +//создание +ai@ai-home:~$ ~/.cargo/bin/spl-token create-token +Creating token Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr under program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + +Address: Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr +Decimals: 9 + +Signature: 656MfR7x4K5fZJEsf1nJTk5gorMkuZtSCw2YGzvtAEHLyftDsYhoXspGspEhD1Jto8pNNfkyNVb2jRVZPBg5gi9u + +------------------------------------------------------------------ +//Эмиссия +ai@ai-home:~$ ~/.cargo/bin/spl-token mint Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr 10 +Minting 10 tokens + Token: Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr + Recipient: AcyCkqNEdR78s6wsuhwEeqfSe4BHGuK1EkzGcUbArifq + +Signature: 5SWjE1cHrcWEnArZuUsx4efSVXKWsADxPsuEZL2KbeWfUGy4DqQe4Mdg3AhKtXMLLmRMeQYSSX1mB7VgzLcbEGao + +ai@ai-home:~$ ~/.cargo/bin/spl-token balance Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr +10 +------------------------------------------------------------------------------ +✅ 2. Перевод токенов на существующий аккаунт +Шаг 1. Создаём токен-аккаунт получателя (один раз) +Вариант A: вручную + +~/.cargo/bin/spl-token create-account <адрес_токена> --owner <публичный_адрес_получателя> + +Вариант B: автоматически при переводе + +~/.cargo/bin/spl-token transfer <адрес_токена> 1 <публичный_адрес_получателя> --fund-recipient + +Флаг --fund-recipient автоматически создаст токен-аккаунт получателя и оплатит аренду за счёт твоего кошелька. + +----- + +ai@ai-home:~$ ~/.cargo/bin/spl-token transfer Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr 1 HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA --fund-recipient +Transfer 1 tokens + Sender: AcyCkqNEdR78s6wsuhwEeqfSe4BHGuK1EkzGcUbArifq + Recipient: HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA + Recipient associated token account: GJQPLqNXZNXATm4J1sGgtiKKCk9wFced2NXhwGxc5hfA + Funding recipient: GJQPLqNXZNXATm4J1sGgtiKKCk9wFced2NXhwGxc5hfA + +Signature: 5R3bGiqC49GBHJFMTGMRvBxNt12nkvmKrwRxUQVcvhyRn23rmr7YAaWxzvedkneuSr3YUmAQXk7UFyorhdr5WvhY + +ai@ai-home:~$ ~/.cargo/bin/spl-token accounts +Token Balance +----------------------------------------------------- +Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr 9 + +ai@ai-home:~$ ~/.cargo/bin/spl-token accounts --owner ^C +ai@ai-home:~$ ~/.cargo/bin/spl-token accounts --owner HMww7YSVfwVm4i8sugqj7wyH26dqzHykzv3wzWwzEvPA +Token Balance +----------------------------------------------------- +Dt7t2kKXYT8UqdioTQZeH4SRXqDA2kh2dscqZQmfr1Rr 1 + diff --git a/solana-shine-client-lib/src/main/java/com/shine/utils/SolanaKeyBase58Converter.java b/solana-shine-client-lib/src/main/java/com/shine/utils/SolanaKeyBase58Converter.java new file mode 100644 index 0000000..8450c94 --- /dev/null +++ b/solana-shine-client-lib/src/main/java/com/shine/utils/SolanaKeyBase58Converter.java @@ -0,0 +1,110 @@ +package com.shine.utils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Класс для конвертации приватного ключа Solana из Base58 в формат JSON-массива чисел, + * который понимает Solana CLI. + * + * Использование: + * 1. Вставьте свой приватный ключ в Base58 в main(). + * 2. Запустите программу — она выведет строку JSON, которую можно сохранить в файл. + * 3. С помощью этого файла можно подключить кошелек в Solana CLI. + */ +public class SolanaKeyBase58Converter { + + // ─────────────────────────────────────────────── + // 🔹 ТЕСТОВЫЙ ЗАПУСК + // ─────────────────────────────────────────────── + public static void main(String[] args) { + // Вставьте сюда свой приватный ключ в Base58 + String base58Key = "5RpEoxRKSr2norQP3vEnq9XokQGh9EbGN8q8xUUVAdm1M5mTD1vMuyJPYJfViMWFf6c8qT5mj2bt64gLE2zm6VG3"; //"ВСТАВЬ_СЮДА_СВОЙ_ПРИВАТНЫЙ_КЛЮЧ"; + + // Конвертация в JSON-массив чисел + String jsonKey = base58ToJson(base58Key); + + // Вывод в консоль + System.out.println("Скопируйте эту строку и сохраните в файл (например, mywallet.json):"); + System.out.println(jsonKey); + } + + // ─────────────────────────────────────────────── + // 🔹 ОСНОВНОЙ МЕТОД КОНВЕРТАЦИИ + // ─────────────────────────────────────────────── + + /** + * Преобразует приватный ключ из Base58 в строку JSON-массива чисел, + * которую можно сохранить в файл для Solana CLI. + * + * @param base58Key приватный ключ в формате Base58 (строка) + * @return строка вида "[25,156,13,48,...,147]" + */ + public static String base58ToJson(String base58Key) { + byte[] bytes = decodeBase58(base58Key); + + // Формируем JSON-массив из байт + StringBuilder json = new StringBuilder("["); + for (int i = 0; i < bytes.length; i++) { + json.append(bytes[i] & 0xFF); // "& 0xFF" нужно, чтобы убрать знак и получить 0–255 + if (i < bytes.length - 1) { + json.append(","); + } + } + json.append("]"); + return json.toString(); + } + + // ─────────────────────────────────────────────── + // 🔹 ДЕКОДЕР BASE58 → БАЙТЫ + // ─────────────────────────────────────────────── + + // Алфавит Base58 (стандарт Solana/Bitcoin) + private static final String BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + + /** + * Декодирует строку Base58 в байтовый массив. + * + * @param input приватный ключ в формате Base58 + * @return байтовый массив приватного ключа + */ + private static byte[] decodeBase58(String input) { + java.math.BigInteger num = java.math.BigInteger.ZERO; + java.math.BigInteger base = java.math.BigInteger.valueOf(58); + + // Переводим Base58 в большое число + for (char c : input.toCharArray()) { + int digit = BASE58_ALPHABET.indexOf(c); + if (digit < 0) { + throw new IllegalArgumentException("Недопустимый символ в Base58: " + c); + } + num = num.multiply(base).add(java.math.BigInteger.valueOf(digit)); + } + + // Конвертируем большое число в байты + List byteList = new ArrayList<>(); + byte[] numBytes = num.toByteArray(); + + // Убираем возможный ведущий 0x00 (для BigInteger) + int startIndex = (numBytes.length > 1 && numBytes[0] == 0) ? 1 : 0; + for (int i = startIndex; i < numBytes.length; i++) { + byteList.add(numBytes[i]); + } + + // Добавляем ведущие нули для каждого символа '1' в Base58 + for (char c : input.toCharArray()) { + if (c == '1') { + byteList.add(0, (byte) 0); + } else { + break; + } + } + + // Преобразуем в обычный массив + byte[] result = new byte[byteList.size()]; + for (int i = 0; i < byteList.size(); i++) { + result[i] = byteList.get(i); + } + return result; + } +} diff --git a/solana-shine-client-lib/src/main/java/com/shine/utils/Wallets.txt b/solana-shine-client-lib/src/main/java/com/shine/utils/Wallets.txt new file mode 100644 index 0000000..80105e2 --- /dev/null +++ b/solana-shine-client-lib/src/main/java/com/shine/utils/Wallets.txt @@ -0,0 +1,37 @@ +solana/phantomWallet.json + // 5RpEoxRKSr2norQP3vEnq9XokQGh9EbGN8q8xUUVAdm1M5mTD1vMuyJPYJfViMWFf6c8qT5mj2bt64gLE2zm6VG3 - тестовые в фантом валет + // FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P + + +Баланс + + + + +✅ 2. Инструкция: как сохранить и подключить ключ в Ubuntu +1. Сохраняем JSON в файл + +После запуска программы скопируй результат, например: + +[25,156,13,48,203,...,147] + +Сохрани в файл mywallet.json: + +echo '[25,156,13,48,203,...,147]' > mywallet.json + +2. Временно подключаем кошелёк в Solana CLI + +Подключаем как текущий кошелёк: + +solana config set --keypair mywallet.json + +Проверяем: + +solana address + +Должен показать публичный ключ, соответствующий этому приватному. +3. Возвращаем обратно свой основной ключ + +После работы верни основной ключ: + +solana config set --keypair ~/.config/solana/id.json